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 │ └────────────────────────────────────────────────────────┘