-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkflow.html
More file actions
342 lines (316 loc) · 17.3 KB
/
workflow.html
File metadata and controls
342 lines (316 loc) · 17.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="CroVault DApp workflow overview"/>
<meta name="keywords" content="CroVault, workflow, how it works, vault, password, encryption"/>
<meta name="author" content="CroVault Team"/>
<meta name="theme-color" content="#051126">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#051126">
<meta name="robots" content="index, follow">
<title>CroVault - Workflow Overview</title>
<!-- Favicons & manifest -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="canonical" href="https://crovault.com/workflow" />
<!-- FontAwesome + Bootstrap -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css">
<!-- Reuse the vault CSS for styling -->
<link rel="stylesheet" href="css/vault.css">
</head>
<body>
<div class="page-container">
<!-- Header -->
<header>
<div id="headerDiv" class="header-content">
<a href="/" title="CroVault homepage">
<img src="assets/images/Icon Transparent/CroVault 480.png" alt="CroVault Logo" title="CroVault Logo"/>
</a>
<div>
<span class="title">CroVault</span>
</div>
</div>
</header>
<!-- Main content -->
<div class="py-3 content">
<section class="section">
<h1 class="text-center">CroVault Workflow Overview</h1>
<p class="text-center">
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.
</p>
</section>
<!-- 1) Page Initialization -->
<section class="section">
<h2>1. Page Initialization</h2>
<p>
<strong>User visits the vault page:</strong> <br>
The page loads <code>vault.js</code> and waits for <code>DOMContentLoaded</code>.
Then:
</p>
<ul>
<li>Web3Modal is initialized.</li>
<li>If <code>web3Modal.cachedProvider</code> is found, the code attempts an auto-connect to the wallet.</li>
<li>A fallback read-only <code>JsonRpcProvider</code> is created to fetch the creation/upsert fees from the CostManager contract.</li>
<li>The DOM is updated to display these fees for the user’s reference.</li>
</ul>
<p>If a wallet is <em>not</em> connected, a “Connect Wallet” button appears so the user can proceed.</p>
</section>
<!-- 2) Connect or View on Cronos Explorer -->
<section class="section">
<h2>2. Connect or View on Cronos Explorer</h2>
<p>
When the user clicks “Connect Wallet”:
</p>
<ul>
<li>
If <code>walletAddress</code> is <strong>not set</strong> (i.e., we are not yet connected):
<ul>
<li>Runs <code>connectWallet()</code>, which attempts repeated wallet connections.</li>
<li>On success, calls <code>afterWalletConnect()</code> to finalize the session.</li>
<li>On failure, sets the button text back to “Connect Wallet.”</li>
</ul>
</li>
<li>
If <code>walletAddress</code> <strong>is already set</strong> (meaning we’re connected):
<ul>
<li>Instead of re-connecting, it opens Cronos Explorer in a new tab for the user’s address:
<br><code>https://explorer.cronos.org/address/<walletAddress></code>
</li>
</ul>
</li>
</ul>
</section>
<!-- 3) afterWalletConnect -->
<section class="section">
<h2>3. afterWalletConnect (Establish Session)</h2>
<ul>
<li>We create an Ethers <code>provider</code> and <code>signer</code>.</li>
<li>We fetch the wallet’s address: <code>(await signer.getAddress()).toLowerCase()</code>.</li>
<li>Update the UI button text to “Connected: 0x1234...ABCD.”</li>
<li>We add a listener for <code>accountsChanged</code> to detect if the user changes or disconnects their wallet:
<ul>
<li>This calls <code>handleIdleTimeout(false)</code> to forcibly lock/hide the vault if the account changes.</li>
</ul>
</li>
<li>We attempt to switch or add the Cronos chain (<code>chainId: 0x19</code>).</li>
<li>Check vaults via <code>factory.ownerToVault(address)</code> for all 4 vaults (VaultContract1-4):
<ul>
<li>If no vaults found, show "Create Vault" button.</li>
<li>If vaults exist, store addresses and call <code>unlockAndLoadAllSections()</code> to load Credentials, Notes, Wallets,
TOTP, PINs, Banks, Credit Cards, Insurances, Identities, Legal Documents, Assets, Contacts, and Subscriptions.</li>
</ul>
</li>
</ul>
</section>
<!-- 4) Create Vault -->
<section class="section">
<h2>4. Create Vault (if needed)</h2>
<p>
If no vault exists for the user’s address, they see a “Create Vault” button.
Clicking it calls <code>createNewVault()</code>:
</p>
<ul>
<li>Calls <code>factory.createVault()</code> four times, each cloning a different VaultContract (Vault 1 to Vault 4).</li>
<li>Each vault stores different types of encrypted data (credentials, pins, bank accounts, legal docs, etc.).</li>
<li>After deployment, we store all vault addresses and proceed to password setup.</li>
</ul>
</section>
<!-- 5) Deriving the Wallet Key (Signature) -->
<section class="section">
<h2>5. Deriving the Wallet Key (Signature)</h2>
<p>
Before encrypting/decrypting data, we call <code>deriveWalletKey()</code>, which:
</p>
<ul>
<li>Asks the user to sign a special message:
<br><code>"I authorize access to my CroVault data on the blockchain"</code>
</li>
<li>Performs a SHA-256 hash on the resulting signature to form <code>walletDerivedKey</code>.</li>
<li>If the user refuses to sign, we keep prompting for a signature whenever encryption/decryption is needed.</li>
</ul>
</section>
<!-- 6) Setting the Vault Password -->
<section class="section">
<h2>6. Setting the Vault Password</h2>
<p>
If the user’s vault is new, or they have no data, they’ll eventually see a <strong>Set Password</strong> modal:
</p>
<ul>
<li>They must enter a 12+ character password meeting complexity rules.</li>
<li>This password is never sent to the server — it’s used client-side to derive encryption keys (AES-GCM) in combination with <code>walletDerivedKey</code>.</li>
<li>Once set, it cannot be changed (the only way to reset is to delete all vault data or deploy a new vault).</li>
</ul>
<p>
If the vault <em>already has data</em>, the user sees an <strong>Unlock</strong> modal:
They must enter the correct password to decrypt existing data.
If it’s wrong, <code>showWrongPasswordModal()</code> appears, letting them retry or cancel.
</p>
</section>
<!-- 7) Viewing/Adding/Editing/Deleting Data -->
<section class="section">
<h2>7. Viewing, Adding, Editing, or Deleting Data</h2>
<ul>
<li><strong>Read from chain:</strong>
<code>readCredentials()</code>, <code>readNote()</code>, <code>readWalletAddress()</code>, <code>readTOTP()</code>,
<code>readPins()</code>, <code>readBankAccounts()</code>, <code>readCreditCards()</code>,
<code>readInsurances()</code>, <code>readIdentities()</code>, <code>readLegalDocuments()</code>,
<code>readAssets()</code>, <code>readContacts()</code>, and <code>readSubscriptions()</code>
retrieve each item as an encrypted JSON string.
We parse/decrypt with <code>decryptWithPassword(sessionPassword, ...)</code>.
</li>
<li><strong>Add/Edit data:</strong>
<ul>
<li>Items go into <code>pendingCredentials</code>, <code>pendingNotes</code>, <code>pendingWallets</code>, <code>pendingTotps</code>,</li>
<li><code>pendingPins</code>, <code>pendingBankAccounts</code>, <code>pendingCreditCards</code>,</li>
<li><code>pendingInsurances</code>, <code>pendingIdentities</code>, <code>pendingLegalDocuments</code>,</li>
<li><code>pendingAssets</code>, <code>pendingContacts</code>, <code>pendingSubscriptions</code>.</li>
<li>The user sees these as “(Pending)” until they click “Save All.”</li>
</ul>
</li>
<li><strong>Save All:</strong>
<ul>
<li>Encrypt each pending item with <code>encryptWithPassword()</code> (AES-GCM) and send to the appropriate contract’s <code>upsert</code> methods with <code>value = upsertCost</code>.</li>
<li>After mining, we re-fetch and re-decrypt the data so the UI is up to date.</li>
</ul>
</li>
<li><strong>Delete items:</strong>
<ul>
<li>Calls <code>deleteCredentials(ids)</code>, <code>deleteNotes(ids)</code>, <code>deleteWalletAddresses(ids)</code>, <code>deleteTOTP(ids)</code>,</li>
<li><code>deletePins(ids)</code>, <code>deleteBankAccounts(ids)</code>, <code>deleteCreditCards(ids)</code>,</li>
<li><code>deleteInsurances(ids)</code>, <code>deleteIdentities(ids)</code>, <code>deleteLegalDocuments(ids)</code>,</li>
<li><code>deleteAssets(ids)</code>, <code>deleteContacts(ids)</code>, <code>deleteSubscriptions(ids)</code>.</li>
<li>Then re-loads from chain to refresh the UI.</li>
</ul>
</li>
</ul>
</section>
<!-- 8) Idle Timeout & Session Reset -->
<section class="section">
<h2>8. Idle Timeout & Session Reset</h2>
<p>
The DApp enforces a 2.5-minute idle timer:
</p>
<ul>
<li>If no user activity (click, scroll, keypress) occurs, <code>handleIdleTimeout(true)</code> fires.</li>
<li>We immediately hide the vault, clear <code>sessionPassword</code> and <code>walletDerivedKey</code>, and show an alert about the session reset.</li>
<li>The user must re-sign and re-enter the password to resume.</li>
<li>If the user manually changes accounts in the wallet, we call <code>handleIdleTimeout(false)</code> (no alert) but still reset and hide the vault.</li>
</ul>
</section>
<!-- 9) Resetting the Password (Delete All Data) -->
<section class="section">
<h2>9. Resetting the Password (Delete All Data)</h2>
<p>
There’s no built-in method to “change” your vault password.
Instead, if you want a fresh password, you must:
</p>
<ol>
<li>Delete all items (credentials, notes, wallets) from your vault or deploy a new vault.</li>
<li>Next time you add data, you can set a brand-new password.</li>
</ol>
</section>
<!-- 10) Summary Diagram (Textual) -->
<section class="section">
<h2>10. Summary Diagram (Textual)</h2>
<p>The overall state flow in text form:</p>
<pre class="white" style="background:#333; padding:1em; overflow:auto;">
┌───────────┐
│ Page Load │
└─────┬─────┘
│
v
┌───────────────────────────┐
│ Check Cached Web3Provider │
└────────────┬──────────────┘
│No
v
[Show Connect Button]
│User clicks
v
┌──────────────────────┐
│ connectWallet() │
│ -> afterWalletConnect│
└──────────┬───────────┘
│Yes
v
┌───────────────────────────────┐
│ Wallet is connected -> Button │
│ links to Cronos Explorer │
└───────────────────────────────┘
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 │
└────────────────────────────────────────────────────────┘
</pre>
</section>
</div>
<!-- Footer -->
<footer class="mt-4">
<p>
<strong>© <span id="year"></span> CroVault. All Rights Reserved.</strong>
|
<a href="/privacy.html" class="text-light">Privacy Policy</a>
|
<a href="/terms.html" class="text-light">Terms and Conditions</a>
|
<a href="/LICENSE.html" class="text-light">MIT License</a>
</p>
<p>
⚠️ Disclaimer: CroVault is a decentralized application. You are solely responsible for your data, wallet, and password. We cannot recover lost vaults.
</p>
<div>
<a href="https://x.com/Swerfter" title="Twitter/X" class="social-link sl-style">
<i class="fab fa-x-twitter"></i>
</a>
</div>
</footer>
</div>
<!-- A small script to fill the footer year -->
<script>
document.addEventListener("DOMContentLoaded", () => {
document.getElementById("year").textContent = new Date().getFullYear();
});
</script>
</body>
</html>