CroVault Logo
CroVault

CroVault Workflow Overview

This page describes the major steps and states in the CroVault DApp workflow, from first visiting the Vault page through connecting a wallet, deriving a key, creating a vault, unlocking the data, saving items, and handling idle timeouts.

1. Page Initialization

User visits the vault page:
The page loads vault.js and waits for DOMContentLoaded. Then:

  • Web3Modal is initialized.
  • If web3Modal.cachedProvider is found, the code attempts an auto-connect to the wallet.
  • A fallback read-only JsonRpcProvider is created to fetch the creation/upsert fees from the CostManager contract.
  • The DOM is updated to display these fees for the user’s reference.

If a wallet is not connected, a “Connect Wallet” button appears so the user can proceed.

2. Connect or View on CronoScan

When the user clicks “Connect Wallet”:

  • If walletAddress is not set (i.e., we are not yet connected):
    • Runs connectWallet(), which attempts repeated wallet connections.
    • On success, calls afterWalletConnect() to finalize the session.
    • On failure, sets the button text back to “Connect Wallet.”
  • If walletAddress is already set (meaning we’re connected):
    • Instead of re-connecting, it opens CronoScan in a new tab for the user’s address:
      https://cronoscan.com/address/<walletAddress>

3. afterWalletConnect (Establish Session)

  • We create an Ethers provider and signer.
  • We fetch the wallet’s address: (await signer.getAddress()).toLowerCase().
  • Update the UI button text to “Connected: 0x1234...ABCD.”
  • We add a listener for accountsChanged to detect if the user changes or disconnects their wallet:
    • This calls handleIdleTimeout(false) to forcibly lock/hide the vault if the account changes.
  • We attempt to switch or add the Cronos chain (chainId: 0x19).
  • Check vaults via factory.ownerToVault(address) for all 4 vaults (VaultContract1-4):
    • If no vaults found, show "Create Vault" button.
    • If vaults exist, store addresses and call unlockAndLoadAllSections() to load Credentials, Notes, Wallets, TOTP, PINs, Banks, Credit Cards, Insurances, Identities, Legal Documents, Assets, Contacts, and Subscriptions.

4. Create Vault (if needed)

If no vault exists for the user’s address, they see a “Create Vault” button. Clicking it calls createNewVault():

  • Calls factory.createVault() four times, each cloning a different VaultContract (Vault 1 to Vault 4).
  • Each vault stores different types of encrypted data (credentials, pins, bank accounts, legal docs, etc.).
  • After deployment, we store all vault addresses and proceed to password setup.

5. Deriving the Wallet Key (Signature)

Before encrypting/decrypting data, we call deriveWalletKey(), which:

  • Asks the user to sign a special message:
    "I authorize access to my CroVault data on the blockchain"
  • Performs a SHA-256 hash on the resulting signature to form walletDerivedKey.
  • If the user refuses to sign, we keep prompting for a signature whenever encryption/decryption is needed.

6. Setting the Vault Password

If the user’s vault is new, or they have no data, they’ll eventually see a Set Password modal:

  • They must enter a 12+ character password meeting complexity rules.
  • This password is never sent to the server — it’s used client-side to derive encryption keys (AES-GCM) in combination with walletDerivedKey.
  • Once set, it cannot be changed (the only way to reset is to delete all vault data or deploy a new vault).

If the vault already has data, the user sees an Unlock modal: They must enter the correct password to decrypt existing data. If it’s wrong, showWrongPasswordModal() appears, letting them retry or cancel.

7. Viewing, Adding, Editing, or Deleting Data

  • Read from chain: readCredentials(), readNote(), readWalletAddress(), readTOTP(), readPins(), readBankAccounts(), readCreditCards(), readInsurances(), readIdentities(), readLegalDocuments(), readAssets(), readContacts(), and readSubscriptions() retrieve each item as an encrypted JSON string. We parse/decrypt with decryptWithPassword(sessionPassword, ...).
  • Add/Edit data:
    • Items go into pendingCredentials, pendingNotes, pendingWallets, pendingTotps,
    • pendingPins, pendingBankAccounts, pendingCreditCards,
    • pendingInsurances, pendingIdentities, pendingLegalDocuments,
    • pendingAssets, pendingContacts, pendingSubscriptions.
    • The user sees these as “(Pending)” until they click “Save All.”
  • Save All:
    • Encrypt each pending item with encryptWithPassword() (AES-GCM) and send to the appropriate contract’s upsert methods with value = upsertCost.
    • After mining, we re-fetch and re-decrypt the data so the UI is up to date.
  • Delete items:
    • Calls deleteCredentials(ids), deleteNotes(ids), deleteWalletAddresses(ids), deleteTOTP(ids),
    • deletePins(ids), deleteBankAccounts(ids), deleteCreditCards(ids),
    • deleteInsurances(ids), deleteIdentities(ids), deleteLegalDocuments(ids),
    • deleteAssets(ids), deleteContacts(ids), deleteSubscriptions(ids).
    • Then re-loads from chain to refresh the UI.

8. Idle Timeout & Session Reset

The DApp enforces a 2.5-minute idle timer:

  • If no user activity (click, scroll, keypress) occurs, handleIdleTimeout(true) fires.
  • We immediately hide the vault, clear sessionPassword and walletDerivedKey, and show an alert about the session reset.
  • The user must re-sign and re-enter the password to resume.
  • If the user manually changes accounts in the wallet, we call handleIdleTimeout(false) (no alert) but still reset and hide the vault.

9. Resetting the Password (Delete All Data)

There’s no built-in method to “change” your vault password. Instead, if you want a fresh password, you must:

  1. Delete all items (credentials, notes, wallets) from your vault or deploy a new vault.
  2. Next time you add data, you can set a brand-new password.

10. Summary Diagram (Textual)

The overall state flow in text form:

          ┌───────────┐
          │ Page Load │
          └─────┬─────┘
                │
                v
   ┌───────────────────────────┐
   │ Check Cached Web3Provider │
   └────────────┬──────────────┘
                │No
                v
       [Show Connect Button]
                │User clicks
                v
     ┌──────────────────────┐
     │ connectWallet()      │
     │ -> afterWalletConnect│
     └──────────┬───────────┘
                │Yes
                v
 ┌───────────────────────────────┐
 │ Wallet is connected -> Button │
 │   links to CronoScan          │
 └───────────────────────────────┘


afterWalletConnect():
 ┌────────────────────────────────────────────────────────┐
 │1) Switch to Cronos chain                               │
 │2) walletAddress = getAddress()                         │
 │3) Check vault: factory.ownerToVault(address)           │
 │4) If vault=0x000.. => show "Create Vault"              │
 │   else => userVault & load data => possibly show       │
 │   unlock modal (if data found)                         │
 └────────────────────────────────────────────────────────┘

Create Vault Flow:
 ┌────────────────────────────────────┐
 │ createVault (VaultContract1 clone) │
 │ createVault (VaultContract2 clone) │
 │ createVault (VaultContract3 clone) │
 │ createVault (VaultContract4 clone) │
 │ -> Store all vault addresses       │
 │ -> Show "Your Vault" UI            │
 └────────────────────────────────────┘

Unlock Flow:
 ┌────────────────────────────────────────────────────────┐
 │ If vault has data => showUnlockModal => user pass =>   │
 │ deriveWalletKey => decrypt => show vault => idleTimer  │
 └────────────────────────────────────────────────────────┘

Saving / Editing / Deleting Data:
 ┌────────────────────────────────────────────────────────┐
 │1) read & decrypt existing data                         │
 │2) user modifies => pending arrays => "Save All"        │
 │3) upsert with upsertCost => re-read => re-decrypt      │
 │4) "Delete" calls delete => re-read => UI refresh       │
 └────────────────────────────────────────────────────────┘

Idle Timeout / Account Switch:
 ┌────────────────────────────────────────────────────────┐
 │ If user is idle => handleIdleTimeout(true) => reset    │
 │ session => hide vault => user must unlock again.       │
 │ If accountsChanged => handleIdleTimeout(false).        │
 └────────────────────────────────────────────────────────┘

Reset Password:
 ┌────────────────────────────────────────────────────────┐
 │ Must delete all data or create a new vault => fresh pw │
 └────────────────────────────────────────────────────────┘