fix: ensure crypto initialized before handling messages

Fixed race condition where message handlers could process requests
before cryptoWaitReady() and keyring.loadAll() completed.

Now all message handlers wait for initialization before processing,
which fixes the seed creation failure on first account creation.
This commit is contained in:
2026-02-02 19:34:50 +03:00
parent 084187e67b
commit f5495f7cac
8 changed files with 82 additions and 92 deletions
+2 -1
View File
@@ -14,7 +14,7 @@
},
"sideEffects": false,
"type": "module",
"version": "0.62.21",
"version": "0.62.24",
"versions": {
"git": "0.62.6",
"npm": "0.62.6"
@@ -77,6 +77,7 @@
"@pezkuwi/ui-shared": "^3.17.1",
"@pezkuwi/util": "^14.0.25",
"@pezkuwi/util-crypto": "^14.0.25",
"@pezkuwi/wasm-crypto": "^7.5.18",
"@pezkuwi/x-bigint": "^14.0.25",
"@pezkuwi/x-fetch": "^14.0.25",
"@pezkuwi/x-global": "^14.0.25",
+1 -1
View File
@@ -39,5 +39,5 @@
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
},
"version": "0.62.21"
"version": "0.62.24"
}
+1 -1
View File
@@ -48,5 +48,5 @@
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
},
"version": "0.62.21"
"version": "0.62.24"
}
+1 -1
View File
@@ -15,7 +15,7 @@
},
"sideEffects": false,
"type": "module",
"version": "0.62.21",
"version": "0.62.23",
"scripts": {
"pezkuwi-exec-webpack": "pezkuwi-exec-webpack"
},
+34 -56
View File
@@ -19,13 +19,38 @@ import { cryptoWaitReady } from '@pezkuwi/util-crypto';
// setup the notification (same a FF default background, white text)
withErrorLog(() => chrome.action.setBadgeBackgroundColor({ color: '#d90000' }));
// Initialization promise - handlers must wait for this
let initPromise: Promise<void> | null = null;
function initializeExtension (): Promise<void> {
if (!initPromise) {
initPromise = cryptoWaitReady()
.then((): void => {
console.log('crypto initialized');
keyring.loadAll({ store: new AccountsStore(), type: 'sr25519' });
console.log('initialization completed');
});
}
return initPromise;
}
// Start initialization immediately
initializeExtension().catch((error): void => {
console.error('initialization failed', error);
});
// listen to all messages and handle appropriately
chrome.runtime.onConnect.addListener((port): void => {
// shouldn't happen, however... only listen to what we know about
assert([PORT_CONTENT, PORT_EXTENSION].includes(port.name), `Unknown connection from ${port.name}`);
// message and disconnect handlers
port.onMessage.addListener((data: TransportRequestMessage<keyof RequestSignatures>) => handlers(data, port));
// message and disconnect handlers - wait for init before handling
port.onMessage.addListener((data: TransportRequestMessage<keyof RequestSignatures>) => {
initializeExtension()
.then(() => handlers(data, port))
.catch((error) => console.error('Handler error:', error));
});
port.onDisconnect.addListener(() => console.log(`Disconnected from ${port.name}`));
});
@@ -57,22 +82,17 @@ function getActiveTabs () {
request: { urls }
};
handlers(request);
// Wait for initialization before handling
initializeExtension()
.then(() => handlers(request))
.catch((error) => console.error('Handler error:', error));
});
}
chrome.runtime.onMessage.addListener((message: { type: string }, _, sendResponse): boolean | undefined => {
chrome.runtime.onMessage.addListener((message: { type: string }, _, sendResponse) => {
if (message.type === 'wakeup') {
// Wait for crypto/keyring to be ready before responding awake
waitForInit()
.then(() => sendResponse({ status: 'awake' }))
.catch(() => sendResponse({ status: 'error' }));
// Return true to indicate we will respond asynchronously
return true;
sendResponse({ status: 'awake' });
}
return undefined;
});
// listen to tab updates this is fired on url change
@@ -102,46 +122,4 @@ chrome.tabs.onRemoved.addListener(() => {
getActiveTabs();
});
// Track initialization state
let isInitialized = false;
let initializationPromise: Promise<void> | null = null;
// Wait for initialization before processing - used by wakeup handler
function waitForInit (): Promise<void> {
if (isInitialized) {
return Promise.resolve();
}
if (initializationPromise) {
return initializationPromise;
}
// If init hasn't started yet, start it now
return startInit();
}
function startInit (): Promise<void> {
if (initializationPromise) {
return initializationPromise;
}
initializationPromise = cryptoWaitReady()
.then((): void => {
console.log('crypto initialized');
// load all the keyring data
keyring.loadAll({ store: new AccountsStore(), type: 'sr25519' });
isInitialized = true;
console.log('initialization completed');
})
.catch((error): void => {
console.error('initialization failed', error);
throw error;
});
return initializationPromise;
}
// Start initialization
startInit();
// Note: initialization is handled by initializeExtension() above
+1 -1
View File
@@ -3,4 +3,4 @@
// Do not edit, auto-generated by @pezkuwi/dev
export const packageInfo = { name: '@pezkuwi/extension', path: 'auto', type: 'auto', version: '0.62.21' };
export const packageInfo = { name: '@pezkuwi/extension', path: 'auto', type: 'auto', version: '0.62.23' };
Binary file not shown.
+42 -31
View File
@@ -1750,73 +1750,84 @@ __metadata:
languageName: node
linkType: hard
"@pezkuwi/wasm-bridge@npm:7.5.17":
version: 7.5.17
resolution: "@pezkuwi/wasm-bridge@npm:7.5.17"
"@pezkuwi/wasm-bridge@npm:7.5.15":
version: 7.5.15
resolution: "@pezkuwi/wasm-bridge@npm:7.5.15"
dependencies:
"@pezkuwi/wasm-util": "npm:7.5.17"
"@pezkuwi/wasm-util": "npm:7.5.15"
tslib: "npm:^2.7.0"
peerDependencies:
"@pezkuwi/util": "*"
"@pezkuwi/x-randomvalues": "*"
checksum: 10/a559ccb20388091fe96c59aded45c6146af249f6d8d4cbfd90d00cb818414f2df631abd4d2c59c867f617028d876d334b9d089c4d565da74fcd15ee8147daf05
checksum: 10/70ea6babbd48261d3e6aac8153f309a182ab8a5edb84871bcfdd4418d498a793efdf9623d58f44627b0e731214e2da786f7f5697d7c6ff232a1fb433d9572328
languageName: node
linkType: hard
"@pezkuwi/wasm-crypto-asmjs@npm:7.5.17":
version: 7.5.17
resolution: "@pezkuwi/wasm-crypto-asmjs@npm:7.5.17"
"@pezkuwi/wasm-crypto-asmjs@npm:7.5.15":
version: 7.5.15
resolution: "@pezkuwi/wasm-crypto-asmjs@npm:7.5.15"
dependencies:
tslib: "npm:^2.7.0"
peerDependencies:
"@pezkuwi/util": "*"
checksum: 10/e4f3074edf947a4bf2943e6a100fb8d1bb90c44a369680869e21a3d9756b407cc2901f61bdd19c1f6bfb20ac16093c3a4b694054fd9531f16326c37d57796cd2
checksum: 10/1ff62294d3f7cb2048dd49d7e8bb56d4d9a363ea3bbda7c4c64f57134f63647c58018cc03214ae8942bb4a1d69eb9f166882260326b6fa180652bef0469bba35
languageName: node
linkType: hard
"@pezkuwi/wasm-crypto-init@npm:7.5.17":
version: 7.5.17
resolution: "@pezkuwi/wasm-crypto-init@npm:7.5.17"
"@pezkuwi/wasm-crypto-init@npm:7.5.15":
version: 7.5.15
resolution: "@pezkuwi/wasm-crypto-init@npm:7.5.15"
dependencies:
"@pezkuwi/wasm-bridge": "npm:7.5.17"
"@pezkuwi/wasm-crypto-asmjs": "npm:7.5.17"
"@pezkuwi/wasm-crypto-wasm": "npm:7.5.17"
"@pezkuwi/wasm-util": "npm:7.5.17"
"@pezkuwi/wasm-bridge": "npm:7.5.15"
"@pezkuwi/wasm-crypto-asmjs": "npm:7.5.15"
"@pezkuwi/wasm-crypto-wasm": "npm:7.5.15"
"@pezkuwi/wasm-util": "npm:7.5.15"
tslib: "npm:^2.7.0"
peerDependencies:
"@pezkuwi/util": "*"
"@pezkuwi/x-randomvalues": "*"
checksum: 10/13c60121be0285f0d9c6d023994ee300c6e73a7fcf932334677d7538e8f54bf767428f16f716d4a7f00702a1ea085c70ea074af646fde48d6c127da3398e93a6
checksum: 10/7a0deaa9c5b70d6a443f282c08e7dd11bfbf345f81a7a854663c34e8aeddfa88c64f2302d849d31c0a54569aa115560b323a1b2ae9464928eb63ceefc99b4d91
languageName: node
linkType: hard
"@pezkuwi/wasm-crypto-wasm@npm:7.5.17":
version: 7.5.17
resolution: "@pezkuwi/wasm-crypto-wasm@npm:7.5.17"
"@pezkuwi/wasm-crypto-wasm@npm:7.5.15":
version: 7.5.15
resolution: "@pezkuwi/wasm-crypto-wasm@npm:7.5.15"
dependencies:
"@pezkuwi/wasm-util": "npm:7.5.17"
"@pezkuwi/wasm-util": "npm:7.5.15"
tslib: "npm:^2.7.0"
peerDependencies:
"@pezkuwi/util": "*"
checksum: 10/ce1d9f58b375b51266d9e5e78938476c4e51c70a92126965bf9275415cb73bd4478f0463613d486e43b7f45e7671a29caee1727aa4fb5444ad037ccb22d5bdee
checksum: 10/1c9ac61eda9ed4bd3ba6d267f60724f4379d04c4def51c805a6ccc2463e899a371726b35081ee5fe4d1db55405d3796c3523d184630f9e6b22ea5f628b03c583
languageName: node
linkType: hard
"@pezkuwi/wasm-crypto@npm:7.5.17":
version: 7.5.17
resolution: "@pezkuwi/wasm-crypto@npm:7.5.17"
"@pezkuwi/wasm-crypto@npm:^7.5.18":
version: 7.5.18
resolution: "@pezkuwi/wasm-crypto@npm:7.5.18"
dependencies:
"@noble/hashes": "npm:^1.3.3"
"@pezkuwi/wasm-bridge": "npm:7.5.17"
"@pezkuwi/wasm-crypto-asmjs": "npm:7.5.17"
"@pezkuwi/wasm-crypto-init": "npm:7.5.17"
"@pezkuwi/wasm-crypto-wasm": "npm:7.5.17"
"@pezkuwi/wasm-util": "npm:7.5.17"
"@pezkuwi/wasm-bridge": "npm:7.5.15"
"@pezkuwi/wasm-crypto-asmjs": "npm:7.5.15"
"@pezkuwi/wasm-crypto-init": "npm:7.5.15"
"@pezkuwi/wasm-crypto-wasm": "npm:7.5.15"
"@pezkuwi/wasm-util": "npm:7.5.15"
tslib: "npm:^2.7.0"
peerDependencies:
"@pezkuwi/util": "*"
"@pezkuwi/x-randomvalues": "*"
checksum: 10/82c68482d28a59f6d69c9ddfd9493445e87ea5136a6859385970929d0389d1eec80eaf62180cd72ff63fb683bd1074785ae647dfc8dc60c06a3e3aac8c7aa98b
checksum: 10/78a20c98dc6556e0c6d5807c7fb5e42ccf88ffd1c1aad7ef226e5ca3fa550f8b1000441306dd05294cd650de7720d73ff743f2bb8ec260637a38521e2898d76c
languageName: node
linkType: hard
"@pezkuwi/wasm-util@npm:7.5.15":
version: 7.5.15
resolution: "@pezkuwi/wasm-util@npm:7.5.15"
dependencies:
tslib: "npm:^2.7.0"
peerDependencies:
"@pezkuwi/util": "*"
checksum: 10/a6880613a5ec2f6692d8fdb5c8baf91f4621fb9283ec593fc414ad49c9bab0583a0dce57385483c08680a55a4ea890499712338bfbb343e7d644dd6a2e447864
languageName: node
linkType: hard