
Building a Smart Passkey Wallet from scratch with ZKsync Native AA
IntroductionSmart Contract wallets have become very popular with the rise of account abstraction. Account abstraction allows you implementing any signature verification method, enabling your smartphones and computers to become transaction signers, instead of 12-word seed phrases everyone used to have. Additionally, many other programmable features can be attached to build more complex features (e.g spending limits). In this article we are going to build a very simple smart account wallet on Z...

Managing Typescript projects with Monorepo
Building services with lots of code becomes a problematic issue when your application’s scale gets larger. Most of the projects suffer from difficulty of making changes to the codebase after some time, which causes instability of features. Therefore, your application components should be atomic and easily modifiable. There are several ways doing this and most of the big companies utilize these methods. Typescript has lots of advantages on implementing the modularity, since most of the written...

Commit Signature Verification with GPG keys on GitHub
Most of our time is spent on GitHub as developers and we keep contributing to various projects - both open and closed source. There are dozens of GitHub automations are happening in some repositories, sometimes releasing new public versions for applications and libraries. However, we might be having a malicious code injected to the codebase with an unauthorized access to our computers. Signing commits help us preventing impersonation attacks where someone might try to make unauthorized change...
Software Engineer at Clave

Building a Smart Passkey Wallet from scratch with ZKsync Native AA
IntroductionSmart Contract wallets have become very popular with the rise of account abstraction. Account abstraction allows you implementing any signature verification method, enabling your smartphones and computers to become transaction signers, instead of 12-word seed phrases everyone used to have. Additionally, many other programmable features can be attached to build more complex features (e.g spending limits). In this article we are going to build a very simple smart account wallet on Z...

Managing Typescript projects with Monorepo
Building services with lots of code becomes a problematic issue when your application’s scale gets larger. Most of the projects suffer from difficulty of making changes to the codebase after some time, which causes instability of features. Therefore, your application components should be atomic and easily modifiable. There are several ways doing this and most of the big companies utilize these methods. Typescript has lots of advantages on implementing the modularity, since most of the written...

Commit Signature Verification with GPG keys on GitHub
Most of our time is spent on GitHub as developers and we keep contributing to various projects - both open and closed source. There are dozens of GitHub automations are happening in some repositories, sometimes releasing new public versions for applications and libraries. However, we might be having a malicious code injected to the codebase with an unauthorized access to our computers. Signing commits help us preventing impersonation attacks where someone might try to make unauthorized change...
Software Engineer at Clave

Subscribe to Farhad

Subscribe to Farhad
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers


We built Clave V1 as an experiment: a smart account wallet on ZKsync with features like yield and a debit card. No one in the team had previously worked on a real-world React Native project. It worked, but it also had limits. Being tied to one chain, missing new standards, and running on an old tech stack made it harder to grow.
So we decided to start fresh. We stripped Clave down to its basics and rebuilt it for the future: modular, multichain, and built on today’s standards.
Even though Clave V1 packed a rich set of features, the architecture began to show its cracks as we aimed for scale. Here's what held us back:
Clave V1 was deeply tied to ZKsync. While ZKsync gave us native account abstraction, super comfortable dev-EX, and low fees, it also confined us to a single ecosystem with limited liquidity, fewer DeFi integrations, and restricted token support.
Due to the lack of ZKsync's EVM-equivalent compiler during Clave V1's development, we couldn’t deterministically generate the same smart account addresses across other EVM chains. This broke a key promise of a seamless multichain UX and introduced friction for everything from airdrop eligibility to cross-chain identity. It made our wallet feel isolated in the interconnected EVM world.
Clave V1 was started with Expo SDK 48 and utilized ethers.js, which served us well early on. However, over time, the cracks started to show. Expo v48 lacked support for newer native modules, especially on Android, making maintenance of dependencies a nightmare. Animations were clunky, navigation was inconsistent, and the app's responsiveness didn’t meet modern expectations. Debugging became slower and less productive, hurting our velocity. We needed to upgrade the packages and build requirements, but it was too challenging to find the compatible package versions.
Our APIs, client SDKs, the indexer responsible for syncing smart account data, transaction history, on-chain balances, and the ENS resolver were tightly coupled to ZKsync. We were unable to follow the latest developments on ERC-4337 since we did not require it.
Clave V2 is a full-stack rebuild, addressing every pain point we hit in V1:
Runs on Base and Arbitrum today and is deployable to any EVM chain, enabling flexible token support and yield options.
Every part of the application is now chain-agnostic. Running Clave on one more chain is just a one-line change for us.
One of the biggest upgrades in Clave V2 is unified balances. In most wallets, your funds are locked to the chain they live on. For example, if you hold 100 USDC on Base and 100 USDC on Arbitrum, you can’t use all 200 USDC to deposit into an Aave pool on Base. With Clave V2, you can. Thanks to our collaboration with Rhinestone, we use cross-chain intents to treat your multichain portfolio as a single balance. This makes moving and using your funds across chains seamless.
https://x.com/i/status/1945875811204292916
Switched ethers.js to viem for full account abstraction compatibility and performance improvements.
Modular smart contract design following EIP-7579 - powered by Biconomy**.**
Cleaner codebase, less dead weight.
Upgraded to Expo v53 and React 19 with React Compiler.
Moved to React Native's new architecture, improving performance significantly.
Replaced legacy modules with modern, well-supported ones.
What affects you most is probably the application size. We got ~25MB boost.

Upgraded from NestJS version 9 to version 11
Reduced the server-side image sizes by more than 50%

Enhanced bottom sheet UX with @gorhom/bottom-sheet
Fully integrated expo-router for better deeplink handling.
Built a new React Native Passkey library from scratch for better WebAuthn support and error handling.
Completely redesigned animations – react-native-reanimated.
Smoothed transitions –react-native-reanimated
Better keyboard control – react-native-keyboard-controller
Improved Android-specific behaviors – expo-router
Better logging to capture errors much faster with enough context - sentry

Security has always been a top priority for us. Clave V1 was fully audited on ZKsync, but moving to a broader EVM environment required more work. Our yield aggregator needed adjustments, and our account contracts had to be built from scratch. To make sure everything is safe, we went through a complete new round of audits for V2.
Our audits were completed by trusted security firms to make sure our smart contracts and protocols meet the highest security standards.
EVM Accounts:
https://github.com/getclave/audits/blob/master/reports/accounts/evm-accounts_250725_Nethermind.pdf
Clave’s Yield Aggregator (Clagg):
https://github.com/getclave/audits/blob/master/reports/clagg/v2-evm_27072025_Nethermind.pdf
When building Clave, one of the biggest challenges was the lack of strong support for React Native in web3 libraries. Most third-party packages are built for the web and lose proper mobile support over time. Since Clave is mobile-first, we had to step in and make things work:
permissionless.js – does not run on React Native with Expo v53, so we forked it: getclave/permissionless.js
LiFi SDK – also fails on React Native with Expo v53, so we forked it: getclave/lifi-sdk
Passkeys – existing React Native libraries were too complex and did not handle all edge cases. We built our own, extending our ZKsync version to support more devices, especially on Android.
App icons – the existing React Native package for changing app icons does not work with Expo v53. We forked it and made it compatible: getclave/expo-alternate-icons
In short, most of today’s packages are still designed with web apps in mind. We believe the future of web3 is mobile, and stronger mobile support will help the ecosystem grow further.
ERC-7579 gave the ecosystem a common base to build on, but the standard contracts are still not customizable enough and not scalable for real business needs. Many projects focused only on the simplest implementation to get things working. That helped with bootstrapping, but it left behind UX, compatibility, and the needs of real products.
Take permissionless as an example. It is a great step forward, but it does not fully support smart contract features. On top of that, tools like Viem use complex types that are hard to read and hard to customize locally. Even small changes often require a pull request to the main package. We then need to wait for maintainers to upgrade the package before we can access the latest features — and that progress is usually slow.
Building a wallet is never just about adding features. It is about making sure the technology works across chains, feels simple for users, and is strong enough to handle real-world needs. I hope you will like Clave V2 more than you liked Clave V1. Always feel free to reach out for your feedback and feature requests. We are here to shape the future of finance in your pocket.
We built Clave V1 as an experiment: a smart account wallet on ZKsync with features like yield and a debit card. No one in the team had previously worked on a real-world React Native project. It worked, but it also had limits. Being tied to one chain, missing new standards, and running on an old tech stack made it harder to grow.
So we decided to start fresh. We stripped Clave down to its basics and rebuilt it for the future: modular, multichain, and built on today’s standards.
Even though Clave V1 packed a rich set of features, the architecture began to show its cracks as we aimed for scale. Here's what held us back:
Clave V1 was deeply tied to ZKsync. While ZKsync gave us native account abstraction, super comfortable dev-EX, and low fees, it also confined us to a single ecosystem with limited liquidity, fewer DeFi integrations, and restricted token support.
Due to the lack of ZKsync's EVM-equivalent compiler during Clave V1's development, we couldn’t deterministically generate the same smart account addresses across other EVM chains. This broke a key promise of a seamless multichain UX and introduced friction for everything from airdrop eligibility to cross-chain identity. It made our wallet feel isolated in the interconnected EVM world.
Clave V1 was started with Expo SDK 48 and utilized ethers.js, which served us well early on. However, over time, the cracks started to show. Expo v48 lacked support for newer native modules, especially on Android, making maintenance of dependencies a nightmare. Animations were clunky, navigation was inconsistent, and the app's responsiveness didn’t meet modern expectations. Debugging became slower and less productive, hurting our velocity. We needed to upgrade the packages and build requirements, but it was too challenging to find the compatible package versions.
Our APIs, client SDKs, the indexer responsible for syncing smart account data, transaction history, on-chain balances, and the ENS resolver were tightly coupled to ZKsync. We were unable to follow the latest developments on ERC-4337 since we did not require it.
Clave V2 is a full-stack rebuild, addressing every pain point we hit in V1:
Runs on Base and Arbitrum today and is deployable to any EVM chain, enabling flexible token support and yield options.
Every part of the application is now chain-agnostic. Running Clave on one more chain is just a one-line change for us.
One of the biggest upgrades in Clave V2 is unified balances. In most wallets, your funds are locked to the chain they live on. For example, if you hold 100 USDC on Base and 100 USDC on Arbitrum, you can’t use all 200 USDC to deposit into an Aave pool on Base. With Clave V2, you can. Thanks to our collaboration with Rhinestone, we use cross-chain intents to treat your multichain portfolio as a single balance. This makes moving and using your funds across chains seamless.
https://x.com/i/status/1945875811204292916
Switched ethers.js to viem for full account abstraction compatibility and performance improvements.
Modular smart contract design following EIP-7579 - powered by Biconomy**.**
Cleaner codebase, less dead weight.
Upgraded to Expo v53 and React 19 with React Compiler.
Moved to React Native's new architecture, improving performance significantly.
Replaced legacy modules with modern, well-supported ones.
What affects you most is probably the application size. We got ~25MB boost.

Upgraded from NestJS version 9 to version 11
Reduced the server-side image sizes by more than 50%

Enhanced bottom sheet UX with @gorhom/bottom-sheet
Fully integrated expo-router for better deeplink handling.
Built a new React Native Passkey library from scratch for better WebAuthn support and error handling.
Completely redesigned animations – react-native-reanimated.
Smoothed transitions –react-native-reanimated
Better keyboard control – react-native-keyboard-controller
Improved Android-specific behaviors – expo-router
Better logging to capture errors much faster with enough context - sentry

Security has always been a top priority for us. Clave V1 was fully audited on ZKsync, but moving to a broader EVM environment required more work. Our yield aggregator needed adjustments, and our account contracts had to be built from scratch. To make sure everything is safe, we went through a complete new round of audits for V2.
Our audits were completed by trusted security firms to make sure our smart contracts and protocols meet the highest security standards.
EVM Accounts:
https://github.com/getclave/audits/blob/master/reports/accounts/evm-accounts_250725_Nethermind.pdf
Clave’s Yield Aggregator (Clagg):
https://github.com/getclave/audits/blob/master/reports/clagg/v2-evm_27072025_Nethermind.pdf
When building Clave, one of the biggest challenges was the lack of strong support for React Native in web3 libraries. Most third-party packages are built for the web and lose proper mobile support over time. Since Clave is mobile-first, we had to step in and make things work:
permissionless.js – does not run on React Native with Expo v53, so we forked it: getclave/permissionless.js
LiFi SDK – also fails on React Native with Expo v53, so we forked it: getclave/lifi-sdk
Passkeys – existing React Native libraries were too complex and did not handle all edge cases. We built our own, extending our ZKsync version to support more devices, especially on Android.
App icons – the existing React Native package for changing app icons does not work with Expo v53. We forked it and made it compatible: getclave/expo-alternate-icons
In short, most of today’s packages are still designed with web apps in mind. We believe the future of web3 is mobile, and stronger mobile support will help the ecosystem grow further.
ERC-7579 gave the ecosystem a common base to build on, but the standard contracts are still not customizable enough and not scalable for real business needs. Many projects focused only on the simplest implementation to get things working. That helped with bootstrapping, but it left behind UX, compatibility, and the needs of real products.
Take permissionless as an example. It is a great step forward, but it does not fully support smart contract features. On top of that, tools like Viem use complex types that are hard to read and hard to customize locally. Even small changes often require a pull request to the main package. We then need to wait for maintainers to upgrade the package before we can access the latest features — and that progress is usually slow.
Building a wallet is never just about adding features. It is about making sure the technology works across chains, feels simple for users, and is strong enough to handle real-world needs. I hope you will like Clave V2 more than you liked Clave V1. Always feel free to reach out for your feedback and feature requests. We are here to shape the future of finance in your pocket.
No activity yet