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.
User visits the vault page:
The page loads vault.js and waits for DOMContentLoaded.
Then:
web3Modal.cachedProvider is found, the code attempts an auto-connect to the wallet.JsonRpcProvider is created to fetch the creation/upsert fees from the CostManager contract.If a wallet is not connected, a “Connect Wallet” button appears so the user can proceed.
When the user clicks “Connect Wallet”:
walletAddress is not set (i.e., we are not yet connected):
connectWallet(), which attempts repeated wallet connections.afterWalletConnect() to finalize the session.walletAddress is already set (meaning we’re connected):
https://cronoscan.com/address/<walletAddress>
provider and signer.(await signer.getAddress()).toLowerCase().accountsChanged to detect if the user changes or disconnects their wallet:
handleIdleTimeout(false) to forcibly lock/hide the vault if the account changes.chainId: 0x19).factory.ownerToVault(address) for all 4 vaults (VaultContract1-4):
unlockAndLoadAllSections() to load Credentials, Notes, Wallets,
TOTP, PINs, Banks, Credit Cards, Insurances, Identities, Legal Documents, Assets, Contacts, and Subscriptions.
If no vault exists for the user’s address, they see a “Create Vault” button.
Clicking it calls createNewVault():
factory.createVault() four times, each cloning a different VaultContract (Vault 1 to Vault 4).
Before encrypting/decrypting data, we call deriveWalletKey(), which:
"I authorize access to my CroVault data on the blockchain"
walletDerivedKey.If the user’s vault is new, or they have no data, they’ll eventually see a Set Password modal:
walletDerivedKey.
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.
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, ...).
pendingCredentials, pendingNotes, pendingWallets, pendingTotps,pendingPins, pendingBankAccounts, pendingCreditCards,pendingInsurances, pendingIdentities, pendingLegalDocuments,pendingAssets, pendingContacts, pendingSubscriptions.encryptWithPassword() (AES-GCM) and send to the appropriate contract’s upsert methods with value = upsertCost.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).The DApp enforces a 2.5-minute idle timer:
handleIdleTimeout(true) fires.sessionPassword and walletDerivedKey, and show an alert about the session reset.handleIdleTimeout(false) (no alert) but still reset and hide the vault.There’s no built-in method to “change” your vault password. Instead, if you want a fresh password, you must:
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 │
└────────────────────────────────────────────────────────┘