Clave Wallet

www.getclave.io
Last Updated: 22-Mar 2024

Stats

Chrome
Chrome
0
Firefox
Firefox
0
Opera
Opera
0
Edge
Edge
0
Android
Android
1000+
IOS
IOS
??
Windows
Windows
0
Mac OS
Mac OS
0
These are best estimates on downloads from various extension and app stores.

Daily Transaction Count

Daily Deployed Clave Account

Daily Active Account Count

Weekly Active Account Count

Activity

Clave Contracts

0 contributors in the last year

Clave Expo Passkey

0 contributors in the last year

Clave Lists

0 contributors in the last year

Security Analysis

Key Management

Responsibility

A single user is responsible for managing the private key (secp256r1passkey in this case).

Storage

The passkey is generated by the device’s Secure Enclave (in case of iOS devices) or similar modules (in case of Android devices). The passkey is locally stored on the device’s Secure Enclave (in case of iOS devices) or similar modules (in case of Android devices).

Access

The user can access Secure Enclave (in case of iOS devices) or similar modules (in case of Android devices) in order to perform different operations without the passkey ever leaving the Secure Enclave.

Account Management

Clave does not support Externally Owned Accounts (EOAs) but it does support Smart Contract Accounts (SCAs).

Clave’s SCA Implementation

Clave maintains their own SCA implementation.

Registry

Clave maintains their own and ModuleManager and HookManager.

Modules

Clave also has 2 module implementations: SocialRecoveryModule and CloudRecoveryModule.

  • SocialRecoveryModule: The Social recovery module allows clave users to assign guardians to their account who can help recovery your wallet.
    1
    struct RecoveryConfig {
    2
    uint128 timelock; // Recovery timelock duration
    3
    uint128 threshold; // Recovery threshold
    4
    address[] guardians; // Guardian addresses
    5
    }

    Each account has a RecoveryConfig which defines:

    1. timelock defines the duration of the recovery period (see recovery section for more context).
    2. threshold defines the minimum number of guardians that need to approve the recovery of an account. Note that the threshold will always be less than or equal to the number of guardians associated with the account.
    3. guardians is an array of guardian addresses associated with an account.

    We’ll discuss how this module is used for recovery in this section.

  • CloudRecoveryModule: The cloud recovery module recovers an account using a key stored in iCloud or other similar clouds. This module is no longer used in the current Clave app because passkeys can sync with different user devices.

Processes

Clave has the following processes in place:

Key Generation
  1. User (mobile wallet) receives a challenge string the Clave server. This challenge string is then used as an input (bytes32 salt) to generate the (counterfactual) account address (using the getAddressForSalt function). A counterfactual account address means that the actual smart contract account is not deployed on the address yet, but if we use the same salt (challenge string) to deploy a smart contract account (using the deployAccount function), it’ll be deployed to the same address that was generated by the getAddressForSalt function.
  2. Once the user has the counterfactual account address, we’ll generate a key pair. In order to do so, we’ll first need to create a publicKeyCredentialCreationOptions object.

    Here is an example (actual implementation might differ) of how the publicKeyCredentialCreationOptions object looks like:

    • challenge parameter is generated using the challenge string that we got from the Clave server (which is randomStringFromServer in the code snippet). This is used to prevent “replay attacks” (more info here).
    • rp which is also known as the relaying party basically defines the describing the organization responsible for registering and authenticating the user. In this case, it’s Clave! (more info here).
    • user defines the user currently registering. The counterfactual account address is used as the id parameter. It is suggested to not use personally identifying information as the id, as it may be stored in an authenticator.  Read the spec (more info here).
    • pubKeyCredParams describes what public key types (in this case, secp256r1) are acceptable to a server (Clave).

    Rest of the params are optionally filled and are same for every user.

    1
    const publicKeyCredentialCreationOptions = {
    2
    challenge: Uint8Array.from(
    3
    randomStringFromServer, c => c.charCodeAt(0)),
    4
    rp: {
    5
    name: "Clave wallet",
    6
    id: "getclave.io",
    7
    },
    8
    user: {
    9
    id: Uint8Array.from(
    10
    "UZSL85T9AFC", c => c.charCodeAt(0)),
    11
    name: "vasa.develop@gmail.com",
    12
    displayName: "vasa",
    13
    },
    14
    pubKeyCredParams: [{alg: -7, type: "public-key"}],
    15
    authenticatorSelection: {
    16
    authenticatorAttachment: "cross-platform",
    17
    },
    18
    timeout: 60000,
    19
    attestation: "direct"
    20
    };
  3. Once we have the publicKeyCredentialCreationOptions, we use the register function to get a PasskeyRegistrationResult object. ThisPasskeyRegistrationResult object is then sent to the clave server to be parsed and validated. Note that under the hood, the register function generates a key pair; the private key is stored in the secure enclave and never leaves the enclave, whereas the public key can be shared publicly.

    1
    import { Passkey, PasskeyRegistrationResult } from 'react-native-passkey';
    2
    3
    // Retrieve a valid FIDO2 attestation request from your server
    4
    // The challenge inside the request needs to be a base64 encoded string
    5
    // There are plenty of libraries which can be used for this (e.g. fido2-lib)
    6
    7
    try {
    8
    // Call the `register` method with the retrieved request in JSON format
    9
    // A native overlay will be displayed
    10
    const result: PasskeyRegistrationResult = await Passkey.register(requestJson);
    11
    12
    // The `register` method returns a FIDO2 attestation result
    13
    // Pass it to your server for verification
    14
    15
    console.log(result);
    16
    17
    // PasskeyRegistrationResult {
    18
    // id: 'ADSUllKQmbqdGtpu4sjseh4cg2TxSvrbcHDTBsv4NSSX9...',
    19
    // rawId: ArrayBuffer(59),
    20
    // response: AuthenticatorAttestationResponse {
    21
    // clientDataJSON: ArrayBuffer(121),
    22
    // attestationObject: ArrayBuffer(306),
    23
    // },
    24
    // type: 'public-key'
    25
    // }
    26
    } catch (error) {
    27
    // Handle Error...
    28
    }
Account Generation/Activation
  1. If everything goes well in step 3, Clave will deploy the smart contract wallet (using the deployAccount function) whenever the user performs their 1st trx from the clave wallet (here is an example transaction ). As we discussed in step 1, the smart contract wallet will be deployed at the counterfactual account address as we will use the same salt to deploy the account that was used to pre generate the address.

    An example transaction showing how Clave wallet deploys user’s SCA on the first transaction from the Clave wallet (trx link)

    The public key (hex encoded version of id fromPasskeyRegistrationResult) will also be passed (within theinitializer parameter) which will set it as the owner of the SCA.

Transaction Process
  • Key signing : The app takes a transaction message and forwards a signing request to the Secure Enclave. The user can then use biometric authentication to approve signing after which the Secure Enclave signs the message with the key.

  • Transaction verification : The signed message from the Secure Enclave is then relayed to the bundler (which is also the sequencer in case of zksync due to native AA support) which sends the transaction to the SCA which uses a verifier contract to validate the secp256r1 signature. Note that in April of 2024, zksync will add native support for EIP-7212, and Clave can then use the native circuit implementation to verify secp256r1 signatures in a much cheaper way.

  • Gas abstraction/sponsership : Clave wallet sponsors first few (~5) transactions using a paymaster.

    An example transaction showing the fee paid by the paymaster.
Account Recovery Process

Clave wallet supports social recovery mechanism where the user can assign their family or friend’s clave address as backup guardians. Users can decide the number of guardians that have to give confirmation for recovery (M our of N guardians where N ≥ M).

The recovery process is conducted by Clave’s smart contract on zkSync. Once the user initiates the recovery flow:

  1. The user is asked to share the address (or nick name that Clave uses as a temporary solution before ENS is added to zksync) that needs to be recovered.
  2. Next, the user is asked the address (or nick name) of their guardian. Note that while Clave’s social recovery module does support recovery using M out of N guardians, but the app currently only works for recovery using a single guardian (i.e. for all users, the threshold is set to 1).
  3. Next, a new passkey is generated (using the process discussed here ). Your device might ask for a biometric authentication to save the newly generated passkey to the cloud (for eg. in case of iOS, it will be stored on the iCloud keychain).
  4. The app will then share a link that the user can share with your guardian. This link contains the details needed by the guardian to generate a signature to initiate the recovery process for the user.
  5. Once the guardian uses the link, they will be prompted to sign a message that signifies their consent to recover the user’s account.
  6. Next, the guardian will sign a transaction that calls the startRecovery function which which will validate the signature from the previous step and start a 48-hour time lock.
  7. Once the 48-hour duration is complete, anyone can call theexecuteRecoveryfunction that will update the owner of the SCA with the new public key that we created in step 3.

Note that the user can chose to cancel the recovery process (using the startRecovery function) anytime within the 48 hours time lock period. This feature is useful in case the user initiated the recovery process by mistake or to prevent any unauthorized and malicious activities.

Migrating from another wallet (assuming migration on a single network; zksync)
  • Case 1: If you are migrating from an EOA account: You would need to transfer all your assets from your EOA to the Clave account contract. In future this can be made easier with (EIP-7377 migration transaction).

  • Case 2: If you are migrating from a smart contract account: You would need to transfer all your assets from your smart contract account to the Clave account contract. Ideally, this could be done in a single transaction given we can batch transactions with a smart contract account.

Migrating to another wallet (assuming migration on a single network)

You should be able to transfer all your assets to any other address in a single transaction.

What happens to the wallet if clave servers/platform is down?

TODO

Features

In App

KYC required-
Social login-
Email login-
Passkey login-
Smart Account support-
Portfolio tracking-
On-ramp support-
Off-ramp support-
Watching wallets-
Custom RPC support-
Swap support-
Bridge support-
Stake support-
View NFTs-
Dapp browser-
gas fees customization-
token importing-
Transaction SimulationSimulates a given transaction or user operation and shows the potential outcome
Plugin supportAbility to add plugins to the wallet

Security

Screenshot possibility while doing backup-
Transaction Simulation-

ENS Support

MainnetWhether a user is able to send transactions to a standard ENS (e.g. user.eth) on mainnet
SubdomainsWhether a user is able to send transactions to an ENS subdomain (e.g. hot.user.eth) on mainnet
OffchainWhether a user is able to send transactions to an ENS with an offchain resolver on mainnet.
L2sWhether a user is able to send transactions to an ENS on an L2 (tested on Optimism)
customWhether a user is able to send transactions to an ENS with a custom domain on mainnet (e.g. user.cb.id)

Hardware Wallet Supports

Supported Standards

EIP nameEIP typeEIP statusWallet Support status
ERC-4337: Account Abstraction Using Alt MempoolStandards Track: ERCDraft
ERC-6900: Modular Smart Contract Accounts and PluginsStandards Track: ERCDraft
EIP-7039: Scheme-Handler Discovery Option for WalletsStandards Track: InterfaceDraft
🛑
EIP-7521: General Intents for Smart Contract WalletsStandards Track: ERCDraft
🛑
EIP-7377: Migration TransactionStandards Track: CoreDraft
🛑
ERC-7484: Registry Extension for ERC-7579Standards Track: ERCDraft
🛑
ERC-7529: Contract Discovery and eTLD+1 AssociationStandards Track: ERCDraft
🛑
ERC-7579: Minimal Modular Smart AccountsStandards Track: ERCDraft
🛑
EIP-3085: wallet_addEthereumChain RPC MethodStandards Track: InterfaceReview
ERC-5568: Well-Known Format for Required ActionsStandards Track: ERCReview
🛑
ERC-831: URI Format for EthereumStandards Track: ERCStagnant
EIP-1102: Opt-in account exposureStandards Track: InterfaceStagnant
EIP-1474: Remote procedure call specificationStandards Track: InterfaceStagnant
EIP-2015: wallet_updateEthereumChain RPC MethodStandards Track: InterfaceStagnant
ERC-3224: Described DataStandards Track: ERCStagnant
🛑
EIP-3326: Wallet Switch Ethereum Chain RPC Method (wallet_switchEthereumChain)Standards Track: InterfaceStagnant
ERC-4430: Described TransactionsStandards Track: ERCStagnant
🛑
EIP-5003: Insert Code into EOAs with AUTHUSURPStandards Track: CoreStagnant
🛑
ERC-5139: Remote Procedure Call Provider ListsStandards Track: ERCStagnant
EIP-5792: Wallet Function Call APIStandards Track: InterfaceStagnant
ERC-6384: Human-readable offline signaturesStandards Track: ERCStagnant
EIP-4844: Shard Blob TransactionsStandards Track: CoreLast Call
ERC-681: URL Format for Transaction RequestsStandards Track: ERCFinal
EIP-712: Typed structured data hashing and signingStandards Track: InterfaceFinal
EIP-747: wallet_watchAsset RPC MethodStandards Track: InterfaceFinal
EIP-1193: Ethereum Provider JavaScript APIStandards Track: InterfaceFinal
ERC-1271: Standard Signature Validation Method for ContractsStandards Track: ERCFinal
EIP-1559: Fee market change for ETH 1.0 chainStandards Track: CoreFinal
EIP-2255: Wallet Permissions SystemStandards Track: InterfaceFinal
EIP-2930: Optional access listsStandards Track: CoreFinal
EIP-6492: Signature Validation for Predeploy ContractsStandards Track: ERCFinal
EIP-6963: Multi Injected Provider DiscoveryStandards Track: InterfaceFinal
ERC-945: wallet_scanQRCode RPC Method
RIP-7560: Native Account Abstraction
ERC-7555: Single Sign-On for Account Discovery
🛑

Incentives

No incentives

Security

Audit

Audits in Web3 refer to the process of conducting comprehensive security assessments and evaluations of blockchain-based projects, smart contracts, decentralized applications (dApps), and other Web3 protocols. The purpose of these audits is to identify vulnerabilities, potential risks, and weaknesses in the code and system architecture to enhance security, reliability, and trustworthiness.

AuditorDateAudited VersionCurrent VersionAudit RelevanceAudit Report
CatinaDecember 15, 2023OutdatedLink
CatinaMarch 20, 2024Up to dateLink

Bug Bounty

A bug bounty program in Web3 is an initiative offered by blockchain projects, cryptocurrency platforms, or decentralized applications (dApps) to incentivize security researchers and ethical hackers to discover and report vulnerabilities or bugs in their systems. It is a crowdsourced approach to security testing where individuals or teams are rewarded for responsibly disclosing vulnerabilities they find.

PlatformRewardStatusScope

Past Incidents

TODO