mirror of
https://github.com/zhigang1992/xverse-web-extension.git
synced 2026-01-12 18:02:19 +08:00
Use synchronous listener registration
This commit is contained in:
64
package-lock.json
generated
64
package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"@aryzing/superqs": "0.0.6",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.27.13",
|
||||
"@phosphor-icons/react": "^2.0.10",
|
||||
"@playwright/test": "1.45.2",
|
||||
"@playwright/test": "1.46.1",
|
||||
"@react-spring/web": "^9.6.1",
|
||||
"@sats-connect/core": "0.2.1",
|
||||
"@scure/btc-signer": "1.2.1",
|
||||
@@ -101,7 +101,7 @@
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.6.1",
|
||||
"eslint-plugin-no-inline-styles": "^1.0.5",
|
||||
"eslint-plugin-playwright": "^1.6.0",
|
||||
"eslint-plugin-playwright": "^1.6.2",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
@@ -1394,12 +1394,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz",
|
||||
"integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==",
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.1.tgz",
|
||||
"integrity": "sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.45.2"
|
||||
"playwright": "1.46.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -6514,10 +6514,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-playwright": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.6.0.tgz",
|
||||
"integrity": "sha512-tI1E/EDbHT4Fx5KvukUG3RTIT0gk44gvTP8bNwxLCFsUXVM98ZJG5zWU6Om5JOzH9FrmN4AhMu/UKyEsu0ZoDA==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.6.2.tgz",
|
||||
"integrity": "sha512-mraN4Em3b5jLt01q7qWPyLg0Q5v3KAWfJSlEWwldyUXoa7DSPrBR4k6B6LROLqipsG8ndkwWMdjl1Ffdh15tag==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"examples"
|
||||
],
|
||||
"dependencies": {
|
||||
"globals": "^13.23.0"
|
||||
},
|
||||
@@ -10632,12 +10636,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.45.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz",
|
||||
"integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==",
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz",
|
||||
"integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.45.2"
|
||||
"playwright-core": "1.46.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -10650,9 +10654,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.45.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz",
|
||||
"integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==",
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz",
|
||||
"integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
@@ -15053,11 +15057,11 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@playwright/test": {
|
||||
"version": "1.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz",
|
||||
"integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==",
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.1.tgz",
|
||||
"integrity": "sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==",
|
||||
"requires": {
|
||||
"playwright": "1.45.2"
|
||||
"playwright": "1.46.1"
|
||||
}
|
||||
},
|
||||
"@pmmmwh/react-refresh-webpack-plugin": {
|
||||
@@ -19140,9 +19144,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-plugin-playwright": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.6.0.tgz",
|
||||
"integrity": "sha512-tI1E/EDbHT4Fx5KvukUG3RTIT0gk44gvTP8bNwxLCFsUXVM98ZJG5zWU6Om5JOzH9FrmN4AhMu/UKyEsu0ZoDA==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.6.2.tgz",
|
||||
"integrity": "sha512-mraN4Em3b5jLt01q7qWPyLg0Q5v3KAWfJSlEWwldyUXoa7DSPrBR4k6B6LROLqipsG8ndkwWMdjl1Ffdh15tag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"globals": "^13.23.0"
|
||||
@@ -22038,12 +22042,12 @@
|
||||
}
|
||||
},
|
||||
"playwright": {
|
||||
"version": "1.45.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz",
|
||||
"integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==",
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz",
|
||||
"integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==",
|
||||
"requires": {
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.45.2"
|
||||
"playwright-core": "1.46.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"fsevents": {
|
||||
@@ -22055,9 +22059,9 @@
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
"version": "1.45.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz",
|
||||
"integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw=="
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz",
|
||||
"integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A=="
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.39",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"@aryzing/superqs": "0.0.6",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.27.13",
|
||||
"@phosphor-icons/react": "^2.0.10",
|
||||
"@playwright/test": "1.45.2",
|
||||
"@playwright/test": "1.46.1",
|
||||
"@react-spring/web": "^9.6.1",
|
||||
"@sats-connect/core": "0.2.1",
|
||||
"@scure/btc-signer": "1.2.1",
|
||||
@@ -130,7 +130,7 @@
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.6.1",
|
||||
"eslint-plugin-no-inline-styles": "^1.0.5",
|
||||
"eslint-plugin-playwright": "^1.6.0",
|
||||
"eslint-plugin-playwright": "^1.6.2",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
|
||||
@@ -18,10 +18,10 @@ export default defineConfig({
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 1 : 0,
|
||||
/* Opt to only 2 tests parallel on CI.
|
||||
Note that you may want to change the non-ci amount to a lower number depending on
|
||||
the specs of your computer or if the number of tests increases over time.
|
||||
*/
|
||||
/* Opt to only 2 tests parallel on CI. Note that you may want to change the
|
||||
* non-ci amount to a lower number depending on the specs of your computer or
|
||||
* if the number of tests increases over time.
|
||||
*/
|
||||
workers: process.env.CI ? 2 : 5,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: process.env.CI ? 'blob' : 'html',
|
||||
|
||||
@@ -7,49 +7,84 @@ import { initPermissionsStore, permissionsStoreMutex } from '@components/permiss
|
||||
import { rpcRequestMessageSchema } from '@sats-connect/core';
|
||||
import * as v from 'valibot';
|
||||
|
||||
async function init() {
|
||||
const [error] = await permissionsStoreMutex.runExclusive(initPermissionsStore);
|
||||
if (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to load permissions store:', error);
|
||||
}
|
||||
|
||||
// Listen for connection to the content-script - port for two-way communication
|
||||
chrome.runtime.onConnect.addListener((port) => {
|
||||
if (port.name !== CONTENT_SCRIPT_PORT) return;
|
||||
port.onMessage.addListener((message, messagingPort) => {
|
||||
const parseResult = v.safeParse(rpcRequestMessageSchema, message);
|
||||
|
||||
if (!parseResult.success) {
|
||||
// Assume it's a legacy message when parsing fails.
|
||||
handleLegacyExternalMethodFormat(message, messagingPort);
|
||||
return;
|
||||
}
|
||||
|
||||
handleRPCRequest(parseResult.output, port);
|
||||
});
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
void internalBackgroundMessageHandler(message, sender, sendResponse);
|
||||
// Listener fn must return `true` to indicate the response will be async
|
||||
return true;
|
||||
});
|
||||
|
||||
chrome.runtime.onInstalled.addListener((details) => {
|
||||
if (details.reason === 'install') {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL('options.html#/landing') });
|
||||
let hasInitializationFinished = false;
|
||||
permissionsStoreMutex
|
||||
.runExclusive(initPermissionsStore)
|
||||
.catch(([error]) => {
|
||||
if (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to load permissions store:', error);
|
||||
}
|
||||
})
|
||||
// Even if the store initialization fails, the initialization is considered to
|
||||
// have finished. This allows the app to continue running after a failure
|
||||
// since many of the app's features are not dependent on the permissions
|
||||
// store.
|
||||
.finally(() => {
|
||||
hasInitializationFinished = true;
|
||||
});
|
||||
|
||||
if (process.env.WALLET_LABEL) {
|
||||
chrome.action.setBadgeText({ text: process.env.WALLET_LABEL });
|
||||
} else if (process.env.NODE_ENV === 'development') {
|
||||
chrome.action.setBadgeText({ text: 'DEV' });
|
||||
}
|
||||
// All event handlers that could potentially lead to the permissions store
|
||||
// being accessed should wait for the store to be initialized before
|
||||
// proceeding.
|
||||
async function waitForStoreInitialization() {
|
||||
if (hasInitializationFinished) return;
|
||||
await new Promise((resolve) => {
|
||||
const interval = setInterval(() => {
|
||||
if (hasInitializationFinished) {
|
||||
clearInterval(interval);
|
||||
resolve(undefined);
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
}
|
||||
|
||||
await init().catch((e) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to initialize background script:', e);
|
||||
// Listen for connection to the content-script - port for two-way communication
|
||||
chrome.runtime.onConnect.addListener((port) => {
|
||||
if (port.name !== CONTENT_SCRIPT_PORT) return;
|
||||
|
||||
async function onMessageListener(message: any, messagingPort: chrome.runtime.Port) {
|
||||
await waitForStoreInitialization();
|
||||
const parseResult = v.safeParse(rpcRequestMessageSchema, message);
|
||||
|
||||
if (!parseResult.success) {
|
||||
// Assume it's a legacy message when parsing fails.
|
||||
handleLegacyExternalMethodFormat(message, messagingPort);
|
||||
return;
|
||||
}
|
||||
|
||||
handleRPCRequest(parseResult.output, port);
|
||||
}
|
||||
|
||||
port.onMessage.addListener((message, messagingPort) => {
|
||||
onMessageListener(message, messagingPort).catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to handle message:', error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
void internalBackgroundMessageHandler(message, sender, sendResponse);
|
||||
// Listener fn must return `true` to indicate the response will be async
|
||||
return true;
|
||||
});
|
||||
|
||||
async function onInstalledListener(details: chrome.runtime.InstalledDetails) {
|
||||
await waitForStoreInitialization();
|
||||
if (details.reason === 'install') {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL('options.html#/landing') });
|
||||
}
|
||||
}
|
||||
chrome.runtime.onInstalled.addListener((details) => {
|
||||
onInstalledListener(details).catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Failed to handle onInstalled event:', error);
|
||||
});
|
||||
});
|
||||
|
||||
if (process.env.WALLET_LABEL) {
|
||||
chrome.action.setBadgeText({ text: process.env.WALLET_LABEL });
|
||||
} else if (process.env.NODE_ENV === 'development') {
|
||||
chrome.action.setBadgeText({ text: 'DEV' });
|
||||
}
|
||||
|
||||
2
tests/fixtures/base.ts
vendored
2
tests/fixtures/base.ts
vendored
@@ -32,7 +32,7 @@ export const test = baseTest.extend<{
|
||||
// Xverse opens the landing page on install. Wait for it to load and
|
||||
// use it as the main page by closing the default page.
|
||||
// we give it 5 secs to start up
|
||||
const MAX_STARTUP_TIME = 5000;
|
||||
const MAX_STARTUP_TIME = 5_000;
|
||||
const startTime = Date.now();
|
||||
while (context.pages().length === 1) {
|
||||
if (Date.now() - startTime > MAX_STARTUP_TIME) {
|
||||
|
||||
Reference in New Issue
Block a user