Skip to content

Commit 393a1e2

Browse files
committed
fix: handle corrupted wallets
view-only wallets could previously become broken due to race condition addressed by 79d0db2 this handles those broken wallets
1 parent 79d0db2 commit 393a1e2

1 file changed

Lines changed: 51 additions & 4 deletions

File tree

lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,34 @@ abstract class SWB {
276276
backupWallet['isFavorite'] = wallet.info.isFavourite;
277277
backupWallet['otherDataJsonString'] = wallet.info.otherDataJsonString;
278278

279-
if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) {
280-
backupWallet['viewOnlyWalletDataKey'] =
281-
(await wallet.getViewOnlyWalletData()).toJsonEncodedString();
279+
// Check secure storage for view-only data even if flag is missing.
280+
String? rawViewOnlyData;
281+
if (wallet is ViewOnlyOptionInterface) {
282+
rawViewOnlyData = await _secureStore.read(
283+
key: Wallet.getViewOnlyWalletDataSecStoreKey(
284+
walletId: wallet.walletId,
285+
),
286+
);
287+
}
288+
289+
if (rawViewOnlyData != null) {
290+
backupWallet['viewOnlyWalletDataKey'] = rawViewOnlyData;
291+
// Patch missing isViewOnlyKey flag in otherDataJsonString.
292+
if (wallet.info.otherData[WalletInfoKeys.isViewOnlyKey] != true) {
293+
final patchedOtherData = Map<String, dynamic>.from(
294+
wallet.info.otherData,
295+
);
296+
patchedOtherData[WalletInfoKeys.isViewOnlyKey] = true;
297+
final parsed = ViewOnlyWalletData.fromJsonEncodedString(
298+
rawViewOnlyData,
299+
walletId: wallet.walletId,
300+
);
301+
patchedOtherData[WalletInfoKeys.viewOnlyTypeIndexKey] =
302+
parsed.type.index;
303+
backupWallet['otherDataJsonString'] = jsonEncode(
304+
patchedOtherData,
305+
);
306+
}
282307
} else if (wallet is MnemonicInterface) {
283308
backupWallet['mnemonic'] = await wallet.getMnemonic();
284309
backupWallet['mnemonicPassphrase'] = await wallet
@@ -387,7 +412,7 @@ abstract class SWB {
387412
String? mnemonic, mnemonicPassphrase, privateKey;
388413

389414
ViewOnlyWalletData? viewOnlyData;
390-
if (info.isViewOnly) {
415+
if (info.isViewOnly || walletbackup['viewOnlyWalletDataKey'] is String) {
391416
final viewOnlyDataEncoded =
392417
walletbackup['viewOnlyWalletDataKey'] as String;
393418

@@ -784,6 +809,28 @@ abstract class SWB {
784809
);
785810
}
786811

812+
// Patch missing isViewOnlyKey if backup has view-only data.
813+
if (walletbackup['viewOnlyWalletDataKey'] is String &&
814+
otherData?[WalletInfoKeys.isViewOnlyKey] != true) {
815+
otherData ??= {};
816+
otherData[WalletInfoKeys.isViewOnlyKey] = true;
817+
if (otherData[WalletInfoKeys.viewOnlyTypeIndexKey] == null) {
818+
try {
819+
final parsed = ViewOnlyWalletData.fromJsonEncodedString(
820+
walletbackup['viewOnlyWalletDataKey'] as String,
821+
walletId: walletId,
822+
);
823+
otherData[WalletInfoKeys.viewOnlyTypeIndexKey] = parsed.type.index;
824+
} catch (e, s) {
825+
Logging.instance.e(
826+
"SWB restore: failed to recover viewOnlyTypeIndexKey",
827+
error: e,
828+
stackTrace: s,
829+
);
830+
}
831+
}
832+
}
833+
787834
final info = WalletInfo(
788835
coinName: coin.identifier,
789836
walletId: walletId,

0 commit comments

Comments
 (0)