How does it work?
In this section, we will go through the different technologies and smart contracts used by the Frak Wallet, and how they are working together.
Knowledge base
Before deep diving into the Frak Wallet, it is important to understand a few blockchain technologies.
Account Abstraction
The frak wallet is using the ERC-4337 standard, which is a standard for account abstraction on EVM blockchain.
If you are not familiar with this standard, here is a few great resources to get started:
- Awesome account abstraction
- Stackup intro to account abstraction
- The EIP itself: EIP-4337
A few key takeaways from the account abstraction standard:
- It permit to execute transaction without having to pay for the gas fees directly
- It can be used with any type of validation (password, biometric, etc.)
WebAuthN
Then, the Frak wallet is using the WebAuthN standard for the authentication and the signing of the transactions.
If you are not familiar with this standard, here is a few great resources to get started:
- Awesome WebAuthN
- Detailed WebAuthN demo by Auth0
- WebAuthN demo by Matthew Miller
- WebAuthN official documentation
- WebAuthN on MDN
A few key takeaways from the WebAuthN standard:
- It's a standard for passwordless authentication
- It's a standard for secure message signing
- The authentication is bounded to a specific domain.
P-256 Signature
WebAuthN rely on the secp256r1 signature algorithm (or in short P-256) to sign the transaction.
This signature curve isn't supported on EVM chains by default.
The RIP-7212 provides native support of this curve on rollup chains and is now live on several L2s including Base, Optimism, Arbitrum, and others.
For chains that don't yet support this precompile, we fall back to the FreshCryptoLib to verify the signature in Solidity.
SmartWallet side
In this section we will go through the smart contract related to the Smart wallet side of the Frak Wallet.
We are using the Kernel Smart Wallet by the ZeroDev team for core logic of the Smart Wallet.
It's audited, battle tested, and has a lot of features that we can leverage (for example the ERC-7579 support)
Since kernel wallet support modular validation, we are mainly using two type of validator for the Frak Wallet:
- The main one being the FCL WebAuthN validator, a custom validator developed by us, using the FreshCryptoLib to verify P-256 signatures on chains that don't yet support the RIP-7212 precompile (and using the native precompile where available).
- The second one being the ECDSAValidator, for users that set up recovery options. They can set up an EOA as a recovery wallet, enabling an ECDSAValidator. This permits them to execute transactions via either the WebAuthN validator or the ECDSA one.
On the infrastructure side, we are using the Pimlico bundler to manage the smart wallet transactions and data fetching.
Transaction gas fees are sponsored by Frak for standard SDK interactions. The paymaster handles gas sponsorship automatically through the Pimlico infrastructure.
Communication side
Since the WebAuthN standard is bounded to a specific domain, we use two principal ways of communication:
- An iFrame, for bidirectional communication between the Frak Wallet and the implementing website. This is the primary communication channel used for all SDK actions (modals, embedded wallet, interactions, wallet status, etc.).
- URL-based redirection, used specifically for SSO flows where the user needs to authenticate on the Frak Wallet domain.
Working this way, with a client first approach, provide us a few key benefits:
- We are not relying on third-party cookies
- We don't rely on a centralised server to manage the communication, so you don't have to trust us with up-time, server provisioning, db going down or anything.
- Your app can communication with the client storage, even if the client is offline (so you can still fetch wallet address, transaction history etc. even if the client is offline)
- All the frak related storage is stored on the client storage, in a secure way, and is only accessible by the frak wallet and allowed dApps.
iFrame communication
The iFrame communication side isn't that complex really. We are basically using an iFrame with a two-way communication (using regular window.addEventListener('message', handler)).
The init flow is as follows:
- The dApp create an iFrame with the right URL (can be built using an SDK helper or react component directly)
- When the iFrame is loaded, it should be loaded on the Frak query listener page no UI, juste handling incoming message request.
- Once the frak query listener is loaded, and have warmed up a few key storage slots, it will send a
readymessage to the dApp. - Once the dApp receive the
readymessage, it can start sending message to the Frak Wallet, and receive message from it.
On top of the classical postMessage communication, we added some abstraction around all of that, helping to have:
- a
createIFrameFrakClientmethod, that will build atransport(similar to Viem transports) used for the communication - The
IFrameTransportcan handle every data types specified in theIFrameRpcSchema, - To query data via that transport directly, you can either:
- Use the
requestmethod, returning a Promise of the expectedReturnTypeof the given request - Use the
listenerRequestmethod, and passing acallbackargs, that will be invoked with the expectedReturnTypeof the given request, and every time theReturnTypechange.
- Use the
Under the hood, both request and listenerRequest are using a small abstraction around postMessage, building a notification system, and a request/response system, on both sides.
SSO redirect flow
For SSO (Single Sign-On) authentication, the SDK uses a redirect-based flow:
- The SDK builds a URL with compressed SSO parameters using
prepareSso/openSso - The user is redirected to the Frak Wallet SSO page
- The Frak Wallet handles authentication and creates the session
- The user is redirected back to the dApp, and the SDK picks up the compressed SSO result from the URL
Embedded wallet
The embedded wallet (displayEmbeddedWallet) provides a persistent wallet UI that lives within the host page via the iFrame transport. It supports logged-in views (sharing, referred state) and logged-out views, all rendered within the Frak iFrame without any page redirects.
Cross-origin WebAuthN via iFrame is an evolving w3c standard (see this discussion for background). Browser support is tracked at:
Communication security
Since sensitive data can be shared between the dApp and the Frak Wallet, we built a secured communication layer.
For data exchanged via URL (SSO params, referral context), the SDK uses:
- JSON serialization of the message payload
- A sha256 validation hash of the primordial message keys (varies by message type)
- Base64url encoding of the data + validation hash for URL-safe transport
- On the receiving side, the data is decoded and the validation hash is verified against the payload
For iFrame communication, the postMessage transport includes origin checks to ensure messages are only accepted from the expected Frak Wallet domain.
Transaction side
Now, how does the transaction process work exactly?
We won't enter in depth with the account abstraction way of working, since it's a bit out of the scope of this documentation, and samewise for the WebAuthN signing standard.
Here is the flow when a user want to execute a transaction:
- Build the transaction data
- Prepare a
userOperationbundle - Sign the
userOperation.hashvia the current webAuthN validator - Send the
userOperationto the pimlico bundler, and receive theuserOpHash - Wait for the
userOpHashto be bundled in a transaction, and then wait for thetxHashto be executed