Skip to content

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:

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:

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:

  1. 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).
  2. 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:

  1. 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.).
  2. 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:

  1. The dApp create an iFrame with the right URL (can be built using an SDK helper or react component directly)
  2. When the iFrame is loaded, it should be loaded on the Frak query listener page no UI, juste handling incoming message request.
  3. Once the frak query listener is loaded, and have warmed up a few key storage slots, it will send a ready message to the dApp.
  4. Once the dApp receive the ready message, 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 createIFrameFrakClient method, that will build a transport (similar to Viem transports) used for the communication
  • The IFrameTransport can handle every data types specified in the IFrameRpcSchema,
  • To query data via that transport directly, you can either:
    • Use the request method, returning a Promise of the expected ReturnType of the given request
    • Use the listenerRequest method, and passing a callback args, that will be invoked with the expected ReturnType of the given request, and every time the ReturnType change.

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:

  1. The SDK builds a URL with compressed SSO parameters using prepareSso / openSso
  2. The user is redirected to the Frak Wallet SSO page
  3. The Frak Wallet handles authentication and creates the session
  4. 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:

  1. JSON serialization of the message payload
  2. A sha256 validation hash of the primordial message keys (varies by message type)
  3. Base64url encoding of the data + validation hash for URL-safe transport
  4. 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:

  1. Build the transaction data
  2. Prepare a userOperation bundle
  3. Sign the userOperation.hash via the current webAuthN validator
  4. Send the userOperation to the pimlico bundler, and receive the userOpHash
  5. Wait for the userOpHash to be bundled in a transaction, and then wait for the txHash to be executed