Skip to content

Commit 4561518

Browse files
author
jagdeep sidhu
committed
fix #727
1 parent 42b3dcf commit 4561518

File tree

1 file changed

+141
-114
lines changed

1 file changed

+141
-114
lines changed

source/scripts/Background/controllers/MainController.ts

Lines changed: 141 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import store from 'state/store';
3939
import { loadAndActivateSlip44Vault, saveMainState } from 'state/store';
4040
import {
4141
createAccount,
42+
initializeCleanVaultForSlip44,
4243
forgetWallet,
4344
removeAccount,
4445
setAccountLabel,
@@ -72,6 +73,7 @@ import {
7273
setError as setStoreError,
7374
setIsLoadingBalances,
7475
setNetwork,
76+
setNetworks,
7577
removeNetwork,
7678
setIsPollingUpdate,
7779
startConnecting,
@@ -96,7 +98,10 @@ import {
9698
accountSwitchMutex,
9799
} from 'utils/asyncMutex';
98100
import { areBalancesDifferent } from 'utils/balance';
99-
import { SYSCOIN_UTXO_MAINNET_NETWORK } from 'utils/constants';
101+
import {
102+
SYSCOIN_UTXO_MAINNET_NETWORK,
103+
PALI_NETWORKS_STATE,
104+
} from 'utils/constants';
100105
import { decodeTransactionData } from 'utils/ethUtil';
101106
import { logError } from 'utils/logger';
102107
import { getNetworkChain } from 'utils/network';
@@ -197,6 +202,128 @@ class MainController {
197202
return this.getOrCreatePersistentProvider(mainnet.url);
198203
}
199204

205+
// Centralized reset routine used by both forgetWallet and createWallet(import)
206+
private async resetWalletState(options?: { resetNetworks?: boolean }) {
207+
const { resetNetworks = false } = options || {};
208+
209+
// Clear all timers first to prevent any background operations
210+
this.clearAllTimers();
211+
212+
// Clean up notification manager to prevent memory leaks
213+
notificationManager.cleanup();
214+
215+
// Properly dispose of all keyrings to prevent memory leaks
216+
this.disposeAllKeyrings();
217+
218+
// Clear all keyring instances from memory
219+
this.keyrings.clear();
220+
221+
// Clean up persistent providers
222+
this.cleanupPersistentProviders();
223+
224+
// Cancel any pending async operations
225+
if (this.cancellablePromises.transactionPromise) {
226+
this.cancellablePromises.transactionPromise.cancel();
227+
}
228+
if (this.cancellablePromises.assetsPromise) {
229+
this.cancellablePromises.assetsPromise.cancel();
230+
}
231+
if (this.cancellablePromises.balancePromise) {
232+
this.cancellablePromises.balancePromise.cancel();
233+
}
234+
if (this.cancellablePromises.nftsPromise) {
235+
this.cancellablePromises.nftsPromise.cancel();
236+
}
237+
if (this.currentPromise) {
238+
this.currentPromise.cancel();
239+
this.currentPromise = null;
240+
}
241+
242+
// Stop auto-lock timer
243+
await this.stopAutoLockTimer();
244+
245+
// Reset internal state flags
246+
this.justUnlocked = false;
247+
this.isStartingUp = false;
248+
this.isAccountSwitching = false;
249+
this.isNetworkSwitching = false;
250+
251+
// Clear vault cache
252+
vaultCache.clearCache();
253+
254+
// Clear all in-memory caches and session data
255+
if (this.transactionsManager) {
256+
this.transactionsManager.utils.clearCache();
257+
}
258+
clearProviderCache();
259+
clearFetchBackendAccountCache();
260+
clearRpcCaches();
261+
262+
// Clear all vault-related storage completely
263+
try {
264+
await chromeStorage.removeItem('sysweb3-vault');
265+
await chromeStorage.removeItem('sysweb3-vault-keys');
266+
} catch (error) {
267+
console.error(
268+
'[MainController] Error clearing vault storage during reset:',
269+
error
270+
);
271+
}
272+
273+
// Clear all slip44-specific vault states and persisted Redux state
274+
try {
275+
const allItems = await new Promise<{ [key: string]: any }>(
276+
(resolve, reject) => {
277+
chrome.storage.local.get(null, (items) => {
278+
if (chrome.runtime.lastError) {
279+
reject(
280+
new Error(
281+
`Failed to get all items: ${chrome.runtime.lastError.message}`
282+
)
283+
);
284+
return;
285+
}
286+
resolve(items);
287+
});
288+
}
289+
);
290+
291+
const keysToRemove = Object.keys(allItems).filter(
292+
(key) =>
293+
key.match(/^state-vault-\d+$/) ||
294+
key.startsWith('sysweb3-vault-') ||
295+
key === 'state' ||
296+
key.startsWith('state-')
297+
);
298+
299+
if (keysToRemove.length > 0) {
300+
await Promise.all(
301+
keysToRemove.map((key) => chromeStorage.removeItem(key))
302+
);
303+
}
304+
} catch (error) {
305+
console.error(
306+
'[MainController] Error clearing slip44 vault states during reset:',
307+
error
308+
);
309+
}
310+
311+
// Clear global settings via Redux
312+
store.dispatch(setHasEncryptedVault(false));
313+
store.dispatch(
314+
setAdvancedSettings({
315+
advancedProperty: 'refresh',
316+
value: false,
317+
isFirstTime: true,
318+
})
319+
);
320+
321+
// Optionally reset networks to defaults (used by import flow and forget wallet)
322+
if (resetNetworks) {
323+
store.dispatch(setNetworks(PALI_NETWORKS_STATE));
324+
}
325+
}
326+
200327
/**
201328
* Batch resolve multiple ENS names to addresses using on-chain Multicall3 on Ethereum mainnet.
202329
* Falls back to per-name provider.resolveName for entries that fail (e.g., CCIP-read resolvers).
@@ -1480,121 +1607,10 @@ class MainController {
14801607
// FIRST: Validate password - throws if wrong password or wallet locked
14811608
// This prevents unnecessary cleanup if validation fails
14821609
await this.forgetMainWallet(pwd);
1483-
14841610
// Now proceed with cleanup since password is valid
1485-
// Clear all timers first to prevent any background operations
1486-
this.clearAllTimers();
1487-
1488-
// Clean up notification manager to prevent memory leaks
1489-
notificationManager.cleanup();
1490-
1491-
// Properly dispose of all keyrings to prevent memory leaks
1492-
this.disposeAllKeyrings();
1493-
1494-
// Clear all keyring instances from memory
1495-
this.keyrings.clear();
1496-
1497-
// Clean up persistent providers
1498-
this.cleanupPersistentProviders();
1499-
1500-
// Cancel any pending async operations
1501-
if (this.cancellablePromises.transactionPromise) {
1502-
this.cancellablePromises.transactionPromise.cancel();
1503-
}
1504-
if (this.cancellablePromises.assetsPromise) {
1505-
this.cancellablePromises.assetsPromise.cancel();
1506-
}
1507-
if (this.cancellablePromises.balancePromise) {
1508-
this.cancellablePromises.balancePromise.cancel();
1509-
}
1510-
if (this.cancellablePromises.nftsPromise) {
1511-
this.cancellablePromises.nftsPromise.cancel();
1512-
}
1513-
if (this.currentPromise) {
1514-
this.currentPromise.cancel();
1515-
this.currentPromise = null;
1516-
}
1517-
1518-
// Stop auto-lock timer
1519-
await this.stopAutoLockTimer();
1520-
1521-
// Reset internal state flags
1522-
this.justUnlocked = false;
1523-
this.isStartingUp = false;
1524-
this.isAccountSwitching = false;
1525-
this.isNetworkSwitching = false;
1526-
1527-
// Clear vault cache (no emergency save - we're forgetting the wallet!)
1528-
vaultCache.clearCache();
1529-
1530-
// Clear all in-memory caches and session data
1531-
if (this.transactionsManager) {
1532-
this.transactionsManager.utils.clearCache();
1533-
}
1534-
clearProviderCache();
1535-
clearFetchBackendAccountCache();
1536-
clearRpcCaches();
1537-
1538-
// Clear all vault-related storage completely
1539-
// Remove vault from Chrome storage (both legacy and current keys)
1540-
try {
1541-
await chromeStorage.removeItem('sysweb3-vault');
1542-
await chromeStorage.removeItem('sysweb3-vault-keys');
1543-
} catch (error) {
1544-
console.error('Error clearing vault storage:', error);
1545-
}
1546-
1547-
// Clear all slip44-specific vault states
1548-
try {
1549-
// Note: chromeStorage doesn't have a direct equivalent to chrome.storage.local.get(null)
1550-
// so we'll keep this as direct chrome.storage.local for now as it's a specialized operation
1551-
const allItems = await new Promise<{ [key: string]: any }>(
1552-
(resolve, reject) => {
1553-
chrome.storage.local.get(null, (items) => {
1554-
if (chrome.runtime.lastError) {
1555-
reject(
1556-
new Error(
1557-
`Failed to get all items: ${chrome.runtime.lastError.message}`
1558-
)
1559-
);
1560-
return;
1561-
}
1562-
resolve(items);
1563-
});
1564-
}
1565-
);
1566-
1567-
const keysToRemove = Object.keys(allItems).filter(
1568-
(key) =>
1569-
key.match(/^state-vault-\d+$/) ||
1570-
key.startsWith('sysweb3-vault-') ||
1571-
key === 'state' ||
1572-
key.startsWith('state-')
1573-
);
1574-
1575-
if (keysToRemove.length > 0) {
1576-
// Remove keys individually using chromeStorage
1577-
await Promise.all(
1578-
keysToRemove.map((key) => chromeStorage.removeItem(key))
1579-
);
1580-
}
1581-
} catch (error) {
1582-
console.error('Error clearing slip44 vault states:', error);
1583-
}
1584-
1585-
// Clear global settings via Redux
1586-
store.dispatch(setHasEncryptedVault(false));
1587-
store.dispatch(
1588-
setAdvancedSettings({
1589-
advancedProperty: 'refresh',
1590-
value: false,
1591-
isFirstTime: true,
1592-
})
1593-
);
1594-
1595-
// Reset activeSlip44 to default after forgetting wallet
1596-
// This ensures clean state regardless of what the previous wallet supported
1611+
await this.resetWalletState({ resetNetworks: true });
15971612

1613+
// Reset activeSlip44 to default after forgetting wallet to ensure clean state
15981614
store.dispatch(setActiveSlip44(DEFAULT_UTXO_SLIP44));
15991615
console.log(
16001616
`[MainController] Reset activeSlip44 to default: ${DEFAULT_UTXO_SLIP44}`
@@ -2088,6 +2104,17 @@ class MainController {
20882104

20892105
public async createWallet(password: string, phrase: string): Promise<void> {
20902106
try {
2107+
// Ensure a FULL reset before creating a new wallet (import/fresh create)
2108+
await this.resetWalletState({ resetNetworks: true });
2109+
2110+
// Reset active slip44 and create a TRULY clean vault for default UTXO network
2111+
store.dispatch(setActiveSlip44(DEFAULT_UTXO_SLIP44));
2112+
store.dispatch(forgetWallet());
2113+
store.dispatch(
2114+
// Clean slate: no accounts/assets/txs; sets activeNetwork to provided network
2115+
initializeCleanVaultForSlip44(SYSCOIN_UTXO_MAINNET_NETWORK)
2116+
);
2117+
20912118
// CRITICAL FIX: Ensure vault state is properly initialized before keyring operations
20922119
// The keyring manager expects activeNetwork and activeAccount to exist
20932120
const currentVaultState = store.getState().vault;

0 commit comments

Comments
 (0)