@@ -13,6 +13,7 @@ import type { Maybe } from '~/systems/Core/types';
13
13
import { db } from '~/systems/Core/utils/database' ;
14
14
import { getUniqueString } from '~/systems/Core/utils/string' ;
15
15
import { getTestNoDexieDbData } from '../utils/getTestNoDexieDbData' ;
16
+ import { readFromOPFS } from '~/systems/Core/utils/opfs' ;
16
17
17
18
export type AccountInputs = {
18
19
addAccount : {
@@ -215,68 +216,105 @@ export class AccountService {
215
216
allVaults ,
216
217
backupNetworks ,
217
218
allNetworks ,
219
+ opfsBackupData ,
218
220
] = await Promise . all ( [
219
221
chromeStorage . accounts . getAll ( ) ,
220
222
db . accounts . toArray ( ) ,
221
223
chromeStorage . vaults . getAll ( ) ,
222
224
db . vaults . toArray ( ) ,
223
225
chromeStorage . networks . getAll ( ) ,
224
226
db . networks . toArray ( ) ,
227
+ readFromOPFS ( ) ,
225
228
] ) ;
226
229
230
+ const chromeStorageBackupData = {
231
+ accounts : backupAccounts ,
232
+ vaults : backupVaults ,
233
+ networks : backupNetworks ,
234
+ } ;
235
+
227
236
// if there is no accounts, means the user lost it. try recovering it
228
237
const needsAccRecovery =
229
- allAccounts ?. length === 0 && backupAccounts ?. length > 0 ;
238
+ allAccounts ?. length === 0 &&
239
+ ( chromeStorageBackupData . accounts ?. length > 0 ||
240
+ opfsBackupData ?. accounts ?. length > 0 ) ;
230
241
const needsVaultRecovery =
231
- allVaults ?. length === 0 && backupVaults ?. length > 0 ;
242
+ allVaults ?. length === 0 &&
243
+ ( chromeStorageBackupData . vaults ?. length > 0 ||
244
+ opfsBackupData ?. vaults ?. length > 0 ) ;
232
245
const needsNetworkRecovery =
233
- allNetworks ?. length === 0 && backupNetworks ?. length > 0 ;
246
+ allNetworks ?. length === 0 &&
247
+ ( chromeStorageBackupData . networks ?. length > 0 ||
248
+ opfsBackupData ?. networks ?. length > 0 ) ;
234
249
const needsRecovery =
235
250
needsAccRecovery || needsVaultRecovery || needsNetworkRecovery ;
236
251
237
252
return {
238
- backupAccounts,
239
- backupVaults,
240
- backupNetworks,
241
253
needsRecovery,
242
254
needsAccRecovery,
243
255
needsVaultRecovery,
244
256
needsNetworkRecovery,
257
+ chromeStorageBackupData,
258
+ opfsBackupData,
245
259
} ;
246
260
}
247
261
248
262
static async recoverWallet ( ) {
249
- const {
250
- backupAccounts,
251
- backupVaults,
252
- backupNetworks,
253
- needsRecovery,
254
- needsAccRecovery,
255
- needsVaultRecovery,
256
- needsNetworkRecovery,
257
- } = await AccountService . fetchRecoveryState ( ) ;
263
+ const { chromeStorageBackupData, needsRecovery, opfsBackupData } =
264
+ await AccountService . fetchRecoveryState ( ) ;
258
265
259
266
if ( needsRecovery ) {
260
267
( async ( ) => {
261
268
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
262
269
const dataToLog : any = { } ;
263
270
try {
264
- dataToLog . backupAccounts = JSON . stringify (
265
- backupAccounts ?. map ( ( account ) => account ?. data ?. address ) || [ ]
266
- ) ;
267
- dataToLog . backupNetworks = JSON . stringify ( backupNetworks || [ ] ) ;
271
+ dataToLog . chromeStorageBackupData = {
272
+ ...chromeStorageBackupData ,
273
+ accounts :
274
+ chromeStorageBackupData . accounts ?. map (
275
+ ( account ) => account ?. data ?. address
276
+ ) || [ ] ,
277
+ vaults : chromeStorageBackupData . vaults ?. length || 0 ,
278
+ } ;
268
279
// try getting data from indexedDB (outside of dexie) to check if it's also corrupted
269
280
const testNoDexieDbData = await getTestNoDexieDbData ( ) ;
270
281
dataToLog . testNoDexieDbData = testNoDexieDbData ;
271
282
} catch ( _ ) { }
283
+ try {
284
+ dataToLog . ofpsBackupupData = {
285
+ ...opfsBackupData ,
286
+ accounts :
287
+ opfsBackupData . accounts ?. map (
288
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
289
+ ( account : any ) => account ?. address
290
+ ) || [ ] ,
291
+ vaults : opfsBackupData . vaults ?. length || 0 ,
292
+ } ;
293
+ } catch ( _ ) { }
272
294
273
- Sentry . captureException (
274
- 'Disaster on DB. Start recovering accounts / vaults / networks' ,
275
- {
276
- extra : dataToLog ,
277
- tags : { manual : true } ,
278
- }
279
- ) ;
295
+ const hasOPFSBackup =
296
+ ! ! opfsBackupData ?. accounts ?. length ||
297
+ ! ! opfsBackupData ?. vaults ?. length ||
298
+ ! ! opfsBackupData ?. networks ?. length ;
299
+ const hasChromeStorageBackup =
300
+ ! ! chromeStorageBackupData . accounts ?. length ||
301
+ ! ! chromeStorageBackupData . vaults ?. length ||
302
+ ! ! chromeStorageBackupData . networks ?. length ;
303
+ let sentryMsg = 'DB is cleaned. ' ;
304
+ if ( ! hasOPFSBackup && ! hasChromeStorageBackup ) {
305
+ sentryMsg += 'No backup found. ' ;
306
+ }
307
+ if ( hasOPFSBackup ) {
308
+ sentryMsg += 'OPFS backup is found. Recovering...' ;
309
+ }
310
+ if ( hasChromeStorageBackup ) {
311
+ sentryMsg += 'Chrome Storage backup is found. Recovering...' ;
312
+ }
313
+
314
+ Sentry . captureException ( sentryMsg , {
315
+ extra : dataToLog ,
316
+ tags : { manual : true } ,
317
+ } ) ;
280
318
} ) ( ) ;
281
319
282
320
await db . transaction (
@@ -285,36 +323,84 @@ export class AccountService {
285
323
db . vaults ,
286
324
db . networks ,
287
325
async ( ) => {
288
- if ( needsAccRecovery ) {
289
- let isCurrentFlag = true ;
290
- console . log ( 'recovering accounts' , backupAccounts ) ;
291
- for ( const account of backupAccounts ) {
326
+ console . log ( 'opfsBackupData' , opfsBackupData ) ;
327
+ console . log ( 'chromeStorageBackupData' , chromeStorageBackupData ) ;
328
+ // accounts recovery
329
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
330
+ async function recoverAccounts ( accounts : any ) {
331
+ await db . accounts . clear ( ) ;
332
+ for ( const account of accounts ) {
292
333
// in case of recovery, the first account will be the current
293
- if ( account . key && account . data . address ) {
294
- await db . accounts . add ( {
295
- ...account . data ,
296
- isCurrent : isCurrentFlag ,
297
- } ) ;
298
- isCurrentFlag = false ;
334
+ if ( account . address ) {
335
+ await db . accounts . add ( account ) ;
299
336
}
300
337
}
301
338
}
302
- if ( needsVaultRecovery ) {
303
- console . log ( 'recovering vaults' , backupVaults ) ;
304
- for ( const vault of backupVaults ) {
305
- if ( vault . key && vault . data ) {
306
- await db . vaults . add ( vault . data ) ;
339
+ // vaults recovery
340
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
341
+ async function recoverVaults ( vaults : any ) {
342
+ await db . vaults . clear ( ) ;
343
+ for ( const vault of vaults ) {
344
+ if ( vault . key ) {
345
+ await db . vaults . add ( vault ) ;
307
346
}
308
347
}
309
348
}
310
- if ( needsNetworkRecovery ) {
311
- console . log ( 'recovering networks' , backupNetworks ) ;
312
- for ( const network of backupNetworks ) {
313
- if ( network . key && network . data . id ) {
314
- await db . networks . add ( network . data ) ;
349
+ // networks recovery
350
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
351
+ async function recoverNetworks ( networks : any ) {
352
+ await db . networks . clear ( ) ;
353
+ for ( const network of networks ) {
354
+ if ( network . url ) {
355
+ await db . networks . add ( network ) ;
315
356
}
316
357
}
317
358
}
359
+
360
+ if ( opfsBackupData ?. accounts ?. length ) {
361
+ console . log (
362
+ 'recovering accounts from OPFS' ,
363
+ opfsBackupData . accounts
364
+ ) ;
365
+ await recoverAccounts ( opfsBackupData . accounts ) ;
366
+ } else if ( chromeStorageBackupData . accounts ?. length ) {
367
+ console . log (
368
+ 'recovering accounts from Chrome Storage' ,
369
+ chromeStorageBackupData . accounts
370
+ ) ;
371
+ await recoverAccounts (
372
+ chromeStorageBackupData . accounts ?. map ( ( account ) => account . data )
373
+ ) ;
374
+ }
375
+
376
+ if ( opfsBackupData ?. vaults ?. length ) {
377
+ console . log ( 'recovering vaults from OPFS' , opfsBackupData . vaults ) ;
378
+ await recoverVaults ( opfsBackupData . vaults ) ;
379
+ } else if ( chromeStorageBackupData . vaults ?. length ) {
380
+ console . log (
381
+ 'recovering vaults from Chrome Storage' ,
382
+ chromeStorageBackupData . vaults
383
+ ) ;
384
+ await recoverVaults (
385
+ chromeStorageBackupData . vaults ?. map ( ( vault ) => vault . data )
386
+ ) ;
387
+ }
388
+
389
+ if ( opfsBackupData ?. networks ?. length ) {
390
+ console . log (
391
+ 'recovering networks from OPFS' ,
392
+ opfsBackupData . networks
393
+ ) ;
394
+ await recoverNetworks ( opfsBackupData . networks ) ;
395
+ } else if ( chromeStorageBackupData . networks ?. length ) {
396
+ console . log (
397
+ 'recovering networks from Chrome Storage' ,
398
+ chromeStorageBackupData . networks
399
+ ) ;
400
+ await recoverNetworks (
401
+ chromeStorageBackupData . networks ?. map ( ( network ) => network . data )
402
+ ) ;
403
+ }
318
404
}
319
405
) ;
320
406
}
0 commit comments