# How does it work?

# 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](https://eips.ethereum.org/EIPS/eip-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](https://github.com/4337Mafia/awesome-account-abstraction)
 - [Stackup intro to account abstraction](https://docs.stackup.sh/docs/account-abstraction)
 - The EIP itself: [EIP-4337](https://eips.ethereum.org/EIPS/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](https://w3c.github.io/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](https://github.com/herrjemand/awesome-webauthn)
 - [Detailed WebAuthN demo by Auth0](https://webauthn.me/)
 - [WebAuthN demo by Matthew Miller](https://webauthn.io/)
 - [WebAuthN official documentation](https://w3c.github.io/webauthn/)
 - [WebAuthN on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API)

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](https://neuromancer.sk/std/secg/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](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md) 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](https://github.com/rdubois-crypto/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](https://github.com/zerodevapp/kernel) by the [ZeroDev](https://zerodev.app/) 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](https://erc7579.com/) 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](https://github.com/zerodevapp/kernel/blob/dev/src/validator/webauthn/WebAuthnFclValidator.sol), a custom validator developed by us, using the [FreshCryptoLib](https://github.com/rdubois-crypto/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](https://github.com/zerodevapp/kernel/blob/dev/src/validator/ECDSAValidator.sol), 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](https://www.pimlico.io/) 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, provides 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 communicate 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.

:::note
    On the centralisation side, yeah you are not relying on a centralised server, but you are relying on the frak website, **how is that different?**

    Firstly, the website hosting the Frak wallet is a PWA, meaning that user can install it on their devices (if compatible), and enjoy it everytime (even if our website come down for whatever reason).

    Secondly, it's all open source, meaning that you can easily redeploy it on your own infrastructure if you want to.
:::

### 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, just handling incoming message requests.
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](https://viem.sh/docs/clients/intro.html)) 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](https://github.com/w3c/webauthn/issues/1656) for background). Browser support is tracked at:
 - [Chromium](https://issues.chromium.org/issues/40258856)
 - [Mozilla](https://github.com/mozilla/standards-positions/issues/964)
 - [WebKit](https://github.com/WebKit/standards-positions/issues/304)

### 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.

:::note
    The hash validation mechanism is used for both iFrame communication and URL-based data exchange.
:::

## 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