diff --git a/packages/dashboard/src/initialization/PluginHost.ts b/packages/dashboard/src/initialization/PluginHost.ts index 7810ec800042..848bb1d4954f 100644 --- a/packages/dashboard/src/initialization/PluginHost.ts +++ b/packages/dashboard/src/initialization/PluginHost.ts @@ -4,8 +4,7 @@ import { Emitter } from '@servie/events' import { startPluginDashboard, Plugin } from '@masknet/plugin-infra/dashboard' import { createI18NBundle, i18NextInstance } from '@masknet/shared-base' import { Services, Messages } from '../API' -import { createPartialSharedUIContext } from '../../../mask/shared/plugin-infra/host' -import { RestPartOfPluginUIContextShared } from '../../../mask/src/utils/plugin-context-shared-ui' +import { createSharedContext } from '../../../mask/src/plugin-infra/host' const PluginHost: Plugin.__Host.Host = { minimalMode: { @@ -17,10 +16,7 @@ const PluginHost: Plugin.__Host.Host = { addI18NResource(plugin, resource) { createI18NBundle(plugin, resource)(i18NextInstance) }, - createContext: (id, signal) => ({ - ...createPartialSharedUIContext(id, signal), - ...RestPartOfPluginUIContextShared, - }), + createContext: createSharedContext, } setTimeout(() => { Messages.events.pluginMinimalModeChanged.on(([id, status]) => { diff --git a/packages/mask/.webpack/config.ts b/packages/mask/.webpack/config.ts index e740ead0854a..754c6f9e1c33 100644 --- a/packages/mask/.webpack/config.ts +++ b/packages/mask/.webpack/config.ts @@ -275,7 +275,7 @@ export function createConfiguration(rawFlags: BuildFlags): Configuration { } plugins.push(new WebExtensionPlugin({ background: { entry: 'background', manifest: 3 } })) } else { - entries.background = normalizeEntryDescription(join(__dirname, '../background/mv2-entry.ts')) + entries.background = normalizeEntryDescription(join(__dirname, '../src/background-service.ts')) plugins.push(new WebExtensionPlugin({ background: { entry: 'background', manifest: 2 } })) plugins.push( addHTMLEntry({ diff --git a/packages/mask/background/mv2-entry.ts b/packages/mask/background/mv2-entry.ts deleted file mode 100644 index 2ab526d33c2a..000000000000 --- a/packages/mask/background/mv2-entry.ts +++ /dev/null @@ -1 +0,0 @@ -import './setup' diff --git a/packages/mask/background/mv3-entry.ts b/packages/mask/background/mv3-entry.ts index 2ab526d33c2a..c8c03530c271 100644 --- a/packages/mask/background/mv3-entry.ts +++ b/packages/mask/background/mv3-entry.ts @@ -1 +1,3 @@ import './setup' +import './services/setup' +import './tasks/setup' diff --git a/packages/mask/background/services/helper/request-permission.ts b/packages/mask/background/services/helper/request-permission.ts index 836cc18f3264..d4100ad81876 100644 --- a/packages/mask/background/services/helper/request-permission.ts +++ b/packages/mask/background/services/helper/request-permission.ts @@ -7,8 +7,8 @@ export async function requestExtensionPermission(permission: browser.permissions try { return await browser.permissions.request(permission) } catch { - // which means we're on Firefox or Manifest V3. - // Chrome Manifest v2 allows permission request from the background. + // which means we're on Firefox. + // Chrome allows permission request from the background. } const popup = await browser.windows.create({ height: 600, diff --git a/packages/mask/background/services/setup.ts b/packages/mask/background/services/setup.ts index 71595c6846d1..d9a5c03dfcfd 100644 --- a/packages/mask/background/services/setup.ts +++ b/packages/mask/background/services/setup.ts @@ -19,7 +19,7 @@ setup('Identity', () => import(/* webpackPreload: true */ './identity')) setup('Backup', () => import(/* webpackPreload: true */ './backup')) setup('Helper', () => import(/* webpackPreload: true */ './helper')) setup('SocialNetwork', () => import(/* webpackPreload: true */ './site-adaptors')) -setup('Settings', () => import(/* webpackPreload: true */ './settings'), false) +setup('Settings', () => import(/* webpackPreload: true */ './settings')) setup('ThirdPartyPlugin', () => import(/* webpackPreload: true */ './third-party-plugins')) if (import.meta.webpackHot) { @@ -32,13 +32,13 @@ if (import.meta.webpackHot) { import.meta.webpackHot.accept(['./third-party-plugins'], () => hmr.dispatchEvent(new Event('thirdPartyPlugin'))) } -function setup(key: K, implementation: () => Promise, hasLog = true) { +function setup(key: K, implementation: () => Promise) { const channel = message.events[key].bind(MessageTarget.Broadcast) async function load() { const val = await getLocalImplementation(true, `Services.${key}`, implementation, channel) if (debugMode) { - Reflect.defineProperty(globalThis, key + 'Service', { configurable: true, enumerable: true, value: val }) + Reflect.defineProperty(globalThis, key + 'Service', { configurable: true, value: val }) } return val } @@ -49,15 +49,18 @@ function setup(key: K, implementation: () => Promise + Identity: typeof Identity + Backup: typeof Backup + Helper: typeof Helper + SocialNetwork: {} + Settings: typeof Settings + ThirdPartyPlugin: {} } export type GeneratorServices = { decryption: typeof decryptionWithSocialNetworkDecoding diff --git a/packages/mask/background/setup.ts b/packages/mask/background/setup.ts index 371f9ce312f3..29b6f5270e5d 100644 --- a/packages/mask/background/setup.ts +++ b/packages/mask/background/setup.ts @@ -5,10 +5,7 @@ import { inMemory_KVStorageBackend, indexedDB_KVStorageBackend } from './databas import { setupLegacySettingsAtBackground } from '../shared/legacy-settings/createSettings' import { __deprecated__getStorage, __deprecated__setStorage } from './utils/deprecated-storage' -import './services/setup' -import './tasks/setup' // Setup Tasks import '../shared/site-adaptors' -import '../shared/native-rpc' // setup Android and iOS API server polyfill() setupMaskKVStorageBackend(indexedDB_KVStorageBackend, inMemory_KVStorageBackend) diff --git a/packages/mask/shared/plugin-infra/host.ts b/packages/mask/shared/plugin-infra/host.ts deleted file mode 100644 index 81a1953982dd..000000000000 --- a/packages/mask/shared/plugin-infra/host.ts +++ /dev/null @@ -1,58 +0,0 @@ -// All plugin manager need to call createPluginHost so let's register plugins implicitly. -import './register' -import type { Plugin } from '@masknet/plugin-infra' -import { Emitter } from '@servie/events' -import { MaskMessages } from '../../shared/messages' -import { createI18NBundle, createSubscriptionFromValueRef, i18NextInstance } from '@masknet/shared-base' -import { InMemoryStorages, PersistentStorages } from '../../shared' -import { nativeAPI, hasNativeAPI } from '../../shared/native-rpc' -import { currentMaskWalletAccountSettings, currentMaskWalletChainIdSettings } from '../legacy-settings/wallet-settings' - -export type PartialSharedUIContext = Pick< - Plugin.Shared.SharedUIContext, - 'nativeType' | 'hasNativeAPI' | 'account' | 'chainId' | 'createKVStorage' -> -let sharedUIContextSingleton: Omit -export const createPartialSharedUIContext = (id: string, signal: AbortSignal): PartialSharedUIContext => { - sharedUIContextSingleton ??= { - nativeType: nativeAPI?.type, - hasNativeAPI, - - account: createSubscriptionFromValueRef(currentMaskWalletAccountSettings), - chainId: createSubscriptionFromValueRef(currentMaskWalletChainIdSettings), - } - return { ...createSharedContext(id, signal), ...sharedUIContextSingleton } -} - -export function createSharedContext(pluginID: string, signal: AbortSignal): Plugin.Shared.SharedContext { - return { - createKVStorage(type: 'memory' | 'persistent', defaultValues: T) { - if (type === 'memory') return InMemoryStorages.Plugin.createSubScope(pluginID, defaultValues, signal) - else return PersistentStorages.Plugin.createSubScope(pluginID, defaultValues, signal) - }, - } -} - -export function createPluginHost( - signal: AbortSignal | undefined, - createContext: (plugin: string, signal: AbortSignal) => Context, - getPluginMinimalModeEnabled: (id: string) => Promise, -): Plugin.__Host.Host { - const minimalMode: Plugin.__Host.EnabledStatusReporter = { - isEnabled: getPluginMinimalModeEnabled, - events: new Emitter(), - } - MaskMessages.events.pluginMinimalModeChanged.on( - ([id, val]) => minimalMode.events.emit(val ? 'enabled' : 'disabled', id), - { signal }, - ) - - return { - signal, - minimalMode, - addI18NResource(plugin, resource) { - createI18NBundle(plugin, resource)(i18NextInstance) - }, - createContext, - } -} diff --git a/packages/mask/shared/plugin-infra/register.js b/packages/mask/shared/plugin-infra/register.js deleted file mode 100644 index e213700c7f1f..000000000000 --- a/packages/mask/shared/plugin-infra/register.js +++ /dev/null @@ -1,44 +0,0 @@ -// This file is a JavaScript file because it's reference to the plugins should not be counted as a project reference. -// If your plugin also works in isolated dashboard, please also register it in -// packages/dashboard/src/initialization/plugins.ts -import '@masknet/plugin-example' -import '@masknet/plugin-debugger' -import '@masknet/plugin-flow' -import '@masknet/plugin-file-service' -import '@masknet/plugin-rss3' -import '@masknet/plugin-dao' -import '@masknet/plugin-solana' -import '@masknet/plugin-cyberconnect' -import '@masknet/plugin-go-plus-security' -import '@masknet/plugin-cross-chain-bridge' -import '@masknet/plugin-scamsniffer' -import '../../src/plugins/Wallet' -import '@masknet/plugin-evm' -import '../../src/plugins/RedPacket' -import '../../src/plugins/ITO' -import '../../src/plugins/Snapshot' -import '../../src/plugins/Savings' -import '../../src/plugins/Collectible' -import '../../src/plugins/Transak' -import '../../src/plugins/Gitcoin' -import '../../src/plugins/VCent' -import '../../src/plugins/Trader' -import '../../src/plugins/Avatar' -import '../../src/plugins/Furucombo' -import '../../src/plugins/MaskBox' -import '../../src/plugins/NextID' -import '../../src/plugins/Pets' -import '../../src/plugins/Game' -import '../../src/plugins/CryptoartAI' -import '../../src/plugins/FindTruman' -import '../../src/plugins/ArtBlocks' -import '../../src/plugins/Referral' -import '../../src/plugins/Tips' -import '../../src/plugins/Approval' -import '@masknet/plugin-web3-profile' -// import '../../src/plugins/dHEDGE' -// import '../../src/plugins/External' -// import '../../src/plugins/Polls' -// import '../../src/plugins/PoolTogether' -// import '../../src/plugins/GoodGhosting' -// import '../../src/plugins/UnlockProtocol' diff --git a/packages/mask/shared/tsconfig.json b/packages/mask/shared/tsconfig.json index 799581a214ba..4986e4620092 100644 --- a/packages/mask/shared/tsconfig.json +++ b/packages/mask/shared/tsconfig.json @@ -8,6 +8,5 @@ "lib": ["ES2021"] }, "include": ["./"], - "exclude": ["./plugin-infra/register.js"], "references": [{ "path": "../../shared-base" }, { "path": "../../plugin-infra" }] } diff --git a/packages/mask/src/background-service.ts b/packages/mask/src/background-service.ts index a75535207f3c..4b9915b355bd 100644 --- a/packages/mask/src/background-service.ts +++ b/packages/mask/src/background-service.ts @@ -1,2 +1,9 @@ import '../background/setup' import './extension/service' // setup Services.* +import '../shared/native-rpc' // setup Android and iOS API server +import './extension/background-script/Jobs' // start jobs + +// ! We should gradually stop using i18n in the background +import { addMaskI18N } from '../shared-ui/locales/languages' +import { i18NextInstance } from '@masknet/shared-base' +addMaskI18N(i18NextInstance) diff --git a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx index 6d4faf74463c..04c7deb6aa61 100644 --- a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx +++ b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx @@ -2,7 +2,7 @@ import { Fragment, useEffect, useReducer } from 'react' import { extractTextFromTypedMessage, TypedMessage } from '@masknet/typed-message' import type { ProfileIdentifier } from '@masknet/shared-base' -import Services, { GeneratorServices } from '../../../extension/service' +import Services, { ServicesWithProgress } from '../../../extension/service' import type { DecryptionProgress, FailureDecryption, SuccessDecryption } from './types' import { DecryptPostSuccess } from './DecryptedPostSuccess' import { DecryptPostAwaiting } from './DecryptPostAwaiting' @@ -199,7 +199,7 @@ async function makeProgress( currentSocialNetwork: activatedSocialNetworkUI.encryptionNetwork, } let iv: Uint8Array | undefined - for await (const progress of GeneratorServices.decryption(payload, context)) { + for await (const progress of ServicesWithProgress.decryptionWithSocialNetworkDecoding(payload, context)) { if (signal.aborted) return if (progress.type === DecryptProgressKind.Success) { done(progress.content, iv || new Uint8Array()) diff --git a/packages/mask/background/tasks/Cancellable/StartPluginHost.ts b/packages/mask/src/extension/background-script/Jobs/StartPluginWorker.ts similarity index 74% rename from packages/mask/background/tasks/Cancellable/StartPluginHost.ts rename to packages/mask/src/extension/background-script/Jobs/StartPluginWorker.ts index 102e92e9bbb6..9ad270d96164 100644 --- a/packages/mask/background/tasks/Cancellable/StartPluginHost.ts +++ b/packages/mask/src/extension/background-script/Jobs/StartPluginWorker.ts @@ -1,10 +1,8 @@ import { startPluginWorker, Plugin } from '@masknet/plugin-infra/background-worker' -import { createPluginDatabase } from '../../database/plugin-db' -import { createPluginHost, createSharedContext } from '../../../shared/plugin-infra/host' -import { getPluginMinimalModeEnabled } from '../../services/settings/old-settings-accessor' - +import { createPluginDatabase } from '../../../../background/database/plugin-db' +import { createPluginHost, createSharedContext } from '../../../plugin-infra/host' export default function (signal: AbortSignal) { - startPluginWorker(createPluginHost(signal, createWorkerContext, getPluginMinimalModeEnabled)) + startPluginWorker(createPluginHost(signal, createWorkerContext)) } function createWorkerContext(pluginID: string, signal: AbortSignal): Plugin.Worker.WorkerContext { diff --git a/packages/mask/src/extension/background-script/Jobs/index.ts b/packages/mask/src/extension/background-script/Jobs/index.ts new file mode 100644 index 000000000000..d28977788182 --- /dev/null +++ b/packages/mask/src/extension/background-script/Jobs/index.ts @@ -0,0 +1,2 @@ +import './index_hmr' +import '../../../../background/tasks/setup' diff --git a/packages/mask/src/extension/background-script/Jobs/index_hmr.ts b/packages/mask/src/extension/background-script/Jobs/index_hmr.ts new file mode 100644 index 000000000000..03ca95ce1b62 --- /dev/null +++ b/packages/mask/src/extension/background-script/Jobs/index_hmr.ts @@ -0,0 +1,12 @@ +// Define new task at packages/mask/background/tasks/setup.hmr.ts if possible. +import * as PluginWorker from './StartPluginWorker' + +type CancelableJob = { default: (signal: AbortSignal) => void } +const CancelableJobs: CancelableJob[] = [PluginWorker] + +const abort = new AbortController() +CancelableJobs.map((x) => x.default(abort.signal)) +if (import.meta.webpackHot) { + import.meta.webpackHot.dispose(() => abort.abort()) + import.meta.webpackHot.accept() +} diff --git a/packages/mask/src/extension/dashboard/index.tsx b/packages/mask/src/extension/dashboard/index.tsx index 486f21d94871..1305a375dec4 100644 --- a/packages/mask/src/extension/dashboard/index.tsx +++ b/packages/mask/src/extension/dashboard/index.tsx @@ -7,13 +7,12 @@ import { WalletRPC, WalletMessages } from '../../plugins/Wallet/messages' // import { PluginTraderMessages, PluginTraderRPC } from '../../plugins/Trader/messages' // import { PluginPetMessages } from '../../plugins/Pets/messages' import { MaskMessages } from '../../utils/messages' -import { createPluginHost, createPartialSharedUIContext } from '../../../shared/plugin-infra/host' +import { createPluginHost, createSharedContext } from '../../plugin-infra/host' import type { DashboardPluginMessages, DashboardPluginServices } from '@masknet/shared' import { createNormalReactRoot } from '../../utils/createNormalReactRoot' import { status } from '../../setup.ui' import { PluginTransakMessages } from '../../plugins/Transak/messages' import { PluginTraderMessages } from '../../plugins/Trader/messages' -import { RestPartOfPluginUIContextShared } from '../../utils/plugin-context-shared-ui' const msg: DashboardPluginMessages = { Wallet: WalletMessages, @@ -33,14 +32,5 @@ setMessages(MaskMessages) setPluginServices(rpc) // @ts-ignore setPluginMessages(msg) -startPluginDashboard( - createPluginHost( - undefined, - (id, signal) => ({ - ...createPartialSharedUIContext(id, signal), - ...RestPartOfPluginUIContextShared, - }), - Services.Settings.getPluginMinimalModeEnabled, - ), -) +startPluginDashboard(createPluginHost(undefined, createSharedContext)) status.then(() => createNormalReactRoot()) diff --git a/packages/mask/src/extension/popups/SSR-client.ts b/packages/mask/src/extension/popups/SSR-client.ts index dfc393227e72..bc0c6898ee48 100644 --- a/packages/mask/src/extension/popups/SSR-client.ts +++ b/packages/mask/src/extension/popups/SSR-client.ts @@ -32,7 +32,7 @@ if (location.hash === '#/personas') { }) import(/* webpackPreload: true */ './normal-client') } else { - import(/* webpackPreload: true */ './normal-client').then(() => console.log('then')) + import(/* webpackPreload: true */ './normal-client') } // this function is never called, but it will hint webpack to preload modules we need diff --git a/packages/mask/src/extension/popups/SSR-server.tsx b/packages/mask/src/extension/popups/SSR-server.tsx index e11c5eb54b63..a36224dcd474 100644 --- a/packages/mask/src/extension/popups/SSR-server.tsx +++ b/packages/mask/src/extension/popups/SSR-server.tsx @@ -70,7 +70,7 @@ function PopupSSR(props: PopupSSR_Props) { nickname={props.nickname} /> ) : ( - + )} ({ container: { @@ -47,7 +48,6 @@ const useStyles = makeStyles()(() => ({ interface NormalHeaderProps { onlyTitle?: boolean - onClose(): void } function canNavBack() { @@ -56,7 +56,7 @@ function canNavBack() { } catch {} return false } -export const NormalHeader = memo(({ onlyTitle, onClose }) => { +export const NormalHeader = memo(({ onlyTitle }) => { const { classes } = useStyles() const navigate = useNavigate() const location = useLocation() @@ -78,7 +78,7 @@ export const NormalHeader = memo(({ onlyTitle, onClose }) => if (showClose) { return ( - + Services.Helper.removePopupWindow()} /> {title} ) diff --git a/packages/mask/src/extension/popups/normal-client.tsx b/packages/mask/src/extension/popups/normal-client.tsx index 8e8385f3a5ce..b1760f27e850 100644 --- a/packages/mask/src/extension/popups/normal-client.tsx +++ b/packages/mask/src/extension/popups/normal-client.tsx @@ -1,15 +1,14 @@ -import { status } from '../../setup.ui' import { startPluginDashboard } from '@masknet/plugin-infra/dashboard' import { createNormalReactRoot, hydrateNormalReactRoot } from '../../utils' -import { createPluginHost, createPartialSharedUIContext } from '../../../shared/plugin-infra/host' +import { createPluginHost, createSharedContext } from '../../plugin-infra/host' import { Services } from '../service' +import { status } from '../../setup.ui' import Popups from './UI' import createCache from '@emotion/cache' import { CacheProvider } from '@emotion/react' import { TssCacheProvider } from '@masknet/theme' import { currentPersonaIdentifier } from '../../../shared/legacy-settings/settings' import { setInitialPersonaInformation } from './pages/Personas/hooks/PersonaContextInitialData' -import { RestPartOfPluginUIContextShared } from '../../utils/plugin-context-shared-ui' if (location.hash === '#/personas') { async function hydrate() { @@ -61,14 +60,5 @@ if (location.hash === '#/personas') { function startPluginHost() { // TODO: Should only load plugins when the page is plugin-aware. - startPluginDashboard( - createPluginHost( - undefined, - (id, signal) => ({ - ...createPartialSharedUIContext(id, signal), - ...RestPartOfPluginUIContextShared, - }), - Services.Settings.getPluginMinimalModeEnabled, - ), - ) + startPluginDashboard(createPluginHost(undefined, createSharedContext)) } diff --git a/packages/mask/src/extension/popups/pages/Personas/components/PersonaHeader/index.tsx b/packages/mask/src/extension/popups/pages/Personas/components/PersonaHeader/index.tsx index 37ded4fc7ae5..0d4560dbbafe 100644 --- a/packages/mask/src/extension/popups/pages/Personas/components/PersonaHeader/index.tsx +++ b/packages/mask/src/extension/popups/pages/Personas/components/PersonaHeader/index.tsx @@ -4,7 +4,6 @@ import { PopupRoutes } from '@masknet/shared-base' import { PersonaHeaderUI } from './UI' import { NormalHeader } from '../../../../components/NormalHeader' import { PersonaContext } from '../../hooks/usePersonaContext' -import Services from '../../../../../service' export const PersonaHeader = memo(() => { const navigate = useNavigate() @@ -21,6 +20,6 @@ export const PersonaHeader = memo(() => { nickname={currentPersona.nickname} /> ) : ( - + ) }) diff --git a/packages/mask/src/extension/popups/pages/Wallet/AddDeriveWallet/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/AddDeriveWallet/index.tsx index 209261c2ae90..0e1a88b53b08 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/AddDeriveWallet/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/AddDeriveWallet/index.tsx @@ -10,7 +10,7 @@ import { useWallets } from '@masknet/plugin-infra/web3' import { useI18N } from '../../../../../utils' import { LoadingButton } from '@mui/lab' import { PopupRoutes } from '@masknet/shared-base' -import { currentMaskWalletAccountSettings } from '../../../../../../shared/legacy-settings/wallet-settings' +import { currentMaskWalletAccountSettings } from '../../../../../plugins/Wallet/settings' import { first } from 'lodash-unified' import { useTitle } from '../../../hook/useTitle' diff --git a/packages/mask/src/extension/popups/pages/Wallet/DeleteWallet/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/DeleteWallet/index.tsx index e3460c83b5f5..1fdc2bcc6e4d 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/DeleteWallet/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/DeleteWallet/index.tsx @@ -10,7 +10,7 @@ import { FormattedAddress } from '@masknet/shared' import { WalletRPC } from '../../../../../plugins/Wallet/messages' import { useI18N } from '../../../../../utils' import { PasswordField } from '../../../components/PasswordField' -import { currentMaskWalletAccountSettings } from '../../../../../../shared/legacy-settings/wallet-settings' +import { currentMaskWalletAccountSettings } from '../../../../../plugins/Wallet/settings' import { useWallet } from '@masknet/plugin-infra/web3' import { WalletContext } from '../hooks/useWalletContext' import { useTitle } from '../../../hook/useTitle' diff --git a/packages/mask/src/extension/popups/pages/Wallet/ImportWallet/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/ImportWallet/index.tsx index 9bd585e00c90..92d52c5d2c62 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/ImportWallet/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/ImportWallet/index.tsx @@ -17,7 +17,7 @@ import Services from '../../../../service' import { getDerivableAccounts } from '../../../../../plugins/Wallet/services' import { PageHeader } from '../components/PageHeader' import { PasswordField } from '../../../components/PasswordField' -import { currentMaskWalletAccountSettings } from '../../../../../../shared/legacy-settings/wallet-settings' +import { currentMaskWalletAccountSettings } from '../../../../../plugins/Wallet/settings' import { useWeb3Connection } from '@masknet/plugin-infra/web3' import { NetworkPluginID } from '@masknet/web3-shared-base' import { useTitle } from '../../../hook/useTitle' diff --git a/packages/mask/src/extension/popups/pages/Wallet/components/WalletHeader/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/components/WalletHeader/index.tsx index 220a74b788d7..8492abed9a81 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/components/WalletHeader/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/components/WalletHeader/index.tsx @@ -14,11 +14,10 @@ import { import { Flags } from '../../../../../../../shared' import { MenuItem, Typography } from '@mui/material' import { useMenuConfig, WalletIcon, ChainIcon } from '@masknet/shared' -import { currentMaskWalletAccountSettings } from '../../../../../../../shared/legacy-settings/wallet-settings' +import { currentMaskWalletAccountSettings } from '../../../../../../plugins/Wallet/settings' import { WalletRPC } from '../../../../../../plugins/Wallet/messages' import { NormalHeader } from '../../../../components/NormalHeader' import { NetworkDescriptor, NetworkPluginID } from '@masknet/web3-shared-base' -import Services from '../../../../../service' const useStyles = makeStyles()({ menu: { @@ -88,7 +87,7 @@ export const WalletHeader = memo(() => { }, ) - if (!wallet) return + if (!wallet) return if (matchContractInteraction && wallet) { return ( @@ -120,6 +119,6 @@ export const WalletHeader = memo(() => { {menu} ) : ( - + ) }) diff --git a/packages/mask/src/extension/service-generator.ts b/packages/mask/src/extension/service-generator.ts new file mode 100644 index 000000000000..8daf0b9125b8 --- /dev/null +++ b/packages/mask/src/extension/service-generator.ts @@ -0,0 +1 @@ +export { decryptionWithSocialNetworkDecoding } from '../../background/services/crypto/decryption' diff --git a/packages/mask/src/extension/service.ts b/packages/mask/src/extension/service.ts index e6332be6a431..cf1b90929806 100644 --- a/packages/mask/src/extension/service.ts +++ b/packages/mask/src/extension/service.ts @@ -10,20 +10,10 @@ import { AsyncVersionOf, AsyncGeneratorVersionOf, } from 'async-call-rpc/full' -import { WebExtensionMessage, MessageTarget, assertNotEnvironment, Environment } from '@dimensiondev/holoflows-kit' -import { serializer } from '@masknet/shared-base' -import type { - BackupService, - CryptoService, - GeneratorServices as GeneratorServicesType, - HelperService, - IdentityService, - SettingsService, - SocialNetworkService, - ThirdPartyPluginService, -} from '../../background/services/types' -assertNotEnvironment(Environment.ManifestBackground) +import { isEnvironment, Environment, WebExtensionMessage, MessageTarget } from '@dimensiondev/holoflows-kit' +import { serializer, getLocalImplementation } from '@masknet/shared-base' +const SERVICE_HMR_EVENT = 'service-hmr' const message = new WebExtensionMessage>({ domain: 'services' }) const log: AsyncCallOptions['log'] = { type: 'pretty', @@ -31,34 +21,72 @@ const log: AsyncCallOptions['log'] = { } export const Services = { - Crypto: add('Crypto'), - Identity: add('Identity'), - Backup: add('Backup'), - Helper: add('Helper'), - SocialNetwork: add('SocialNetwork'), - Settings: add('Settings'), - ThirdPartyPlugin: add('ThirdPartyPlugin'), + Crypto: add(() => import('../../background/services/crypto'), 'Crypto'), + Identity: add(() => import('../../background/services/identity'), 'Identity'), + Backup: add(() => import('../../background/services/backup'), 'Backup'), + Helper: add(() => import('../../background/services/helper'), 'Helper'), + SocialNetwork: add(() => import('../../background/services/site-adaptors'), 'SocialNetwork'), + Settings: add(() => import('../../background/services/settings'), 'Settings'), + ThirdPartyPlugin: add(() => import('../../background/services/third-party-plugins'), 'ThirdPartyPlugin'), } export default Services -export const GeneratorServices: AsyncGeneratorVersionOf = add('GeneratorServices', true) as any +export const ServicesWithProgress: AsyncGeneratorVersionOf = add( + () => import('./service-generator'), + 'ServicesWithProgress', + true, +) as any + +if (process.env.manifest === '2' && import.meta.webpackHot && isEnvironment(Environment.ManifestBackground)) { + import.meta.webpackHot.accept( + [ + '../../background/services/crypto', + '../../background/services/identity', + '../../background/services/backup', + '../../background/services/helper', + '../../background/services/settings', + '../../background/services/third-party-plugins', + '../../background/services/site-adaptors', + './service-generator', + ], + () => document.dispatchEvent(new Event(SERVICE_HMR_EVENT)), + ) +} /** - * Helper to add a new service to Services.* / GeneratorServices.* namespace. + * Helper to add a new service to Services.* / ServicesWithProgress.* namespace. + * @param impl Implementation of the service. Should be things like () => import("./background-script/CryptoService") * @param key Name of the service. Used for better debugging. * @param generator Is the service is a generator? */ -function add(key: string, generator = false): AsyncVersionOf { +function add(impl: () => Promise, key: string, generator = false): AsyncVersionOf { const channel: EventBasedChannel | CallbackBasedChannel = message.events[key].bind(MessageTarget.Broadcast) + const isBackground = isEnvironment(Environment.ManifestBackground) const RPC = (generator ? AsyncGeneratorCall : AsyncCall) as any as typeof AsyncCall - const service = RPC(null, { + const load = () => getLocalImplementation(isBackground, `Services.${key}`, impl, channel) + const localImplementation = load() + // No HMR support in MV3 + process.env.manifest === '2' && + isBackground && + import.meta.webpackHot && + document.addEventListener(SERVICE_HMR_EVENT, load) + const service = RPC(localImplementation, { key, serializer, log, channel, - strict: false, + preferLocalImplementation: isBackground, + strict: isBackground, thenable: false, }) - Reflect.set(globalThis, key + 'Service', service) + if (isBackground) { + localImplementation.then((val) => { + Reflect.set(globalThis, key + 'Service', val) + if (isBackground) Reflect.set(Services, key, val) + }) + } else { + Reflect.set(globalThis, key + 'Service', service) + if (isBackground) Reflect.set(Services, key, service) + } return service } diff --git a/packages/mask/src/manifest-v3.json b/packages/mask/src/manifest-v3.json index 411f07514eb7..88f68e76ad58 100644 --- a/packages/mask/src/manifest-v3.json +++ b/packages/mask/src/manifest-v3.json @@ -11,13 +11,7 @@ "action": { "default_popup": "popups.html" }, "homepage_url": "https://mask.io", "description": "The portal to the new & open Internet. Send encrypted message and decentralized Apps right on top of social networks.", - "web_accessible_resources": [ - { - "resources": ["js/*", "*.svg", "*.png", "*.css"], - "matches": [""], - "use_dynamic_url": true - } - ], + "web_accessible_resources": ["*.svg", "*.png", "*.css"], "content_security_policy": { "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';" }, diff --git a/packages/mask/src/plugin-infra/host.ts b/packages/mask/src/plugin-infra/host.ts new file mode 100644 index 000000000000..7a9bf5c1f8b0 --- /dev/null +++ b/packages/mask/src/plugin-infra/host.ts @@ -0,0 +1,118 @@ +// All plugin manager need to call createPluginHost so let's register plugins implicitly. +import './register' +import type { Plugin } from '@masknet/plugin-infra' +import { Emitter } from '@servie/events' +import { MaskMessages } from '../../shared/messages' +import Services from '../extension/service' +import { + createI18NBundle, + createSubscriptionFromAsync, + createSubscriptionFromValueRef, + EMPTY_LIST, + i18NextInstance, +} from '@masknet/shared-base' +import { InMemoryStorages, PersistentStorages } from '../../shared' +import { nativeAPI, hasNativeAPI } from '../../shared/native-rpc' +import { currentMaskWalletAccountSettings, currentMaskWalletChainIdSettings } from '../plugins/Wallet/settings' +import { WalletMessages, WalletRPC } from '../plugins/Wallet/messages' +import type { WalletConnectQRCodeDialogEvent } from '@masknet/plugin-wallet' + +const SharedContext: Omit = { + currentPersona: createSubscriptionFromAsync( + Services.Settings.getCurrentPersonaIdentifier, + undefined, + MaskMessages.events.currentPersonaIdentifier.on, + ), + + nativeType: nativeAPI?.type, + hasNativeAPI, + + send: WalletRPC.sendPayload, + + fetch: Services.Helper.r2d2Fetch, + + openPopupWindow: Services.Helper.openPopupWindow, + closePopupWindow: Services.Helper.removePopupWindow, + + openWalletConnectDialog: (uri: string, callback) => { + const onClose = (ev: WalletConnectQRCodeDialogEvent) => { + if (ev.open) return + callback() + WalletMessages.events.walletConnectQRCodeDialogUpdated.off(onClose) + } + + WalletMessages.events.walletConnectQRCodeDialogUpdated.on(onClose) + WalletMessages.events.walletConnectQRCodeDialogUpdated.sendToLocal({ + open: true, + uri, + }) + }, + closeWalletConnectDialog: () => { + WalletMessages.events.walletConnectQRCodeDialogUpdated.sendToLocal({ + open: false, + }) + }, + + account: createSubscriptionFromValueRef(currentMaskWalletAccountSettings), + chainId: createSubscriptionFromValueRef(currentMaskWalletChainIdSettings), + + wallets: createSubscriptionFromAsync( + () => WalletRPC.getWallets(), + EMPTY_LIST, + WalletMessages.events.walletsUpdated.on, + ), + walletPrimary: createSubscriptionFromAsync( + () => WalletRPC.getWalletPrimary(), + null, + WalletMessages.events.walletsUpdated.on, + ), + + personaSignMessage: Services.Identity.signWithPersona, + + updateAccount: WalletRPC.updateMaskAccount, + resetAccount: WalletRPC.resetMaskAccount, + selectAccount: WalletRPC.selectMaskAccount, + + signTransaction: WalletRPC.signTransaction, + signTypedData: WalletRPC.signTypedData, + signPersonalMessage: WalletRPC.signPersonalMessage, + + getWallets: WalletRPC.getWallets, + getWalletPrimary: WalletRPC.getWalletPrimary, + addWallet: WalletRPC.updateWallet, + updateWallet: WalletRPC.updateWallet, + removeWallet: WalletRPC.removeWallet, +} + +export function createSharedContext(pluginID: string, signal: AbortSignal): Plugin.Shared.SharedContext { + return { + createKVStorage(type: 'memory' | 'persistent', defaultValues: T) { + if (type === 'memory') return InMemoryStorages.Plugin.createSubScope(pluginID, defaultValues) + else return PersistentStorages.Plugin.createSubScope(pluginID, defaultValues) + }, + ...SharedContext, + } +} + +export function createPluginHost( + signal: AbortSignal | undefined, + createContext: (plugin: string, signal: AbortSignal) => Context, +): Plugin.__Host.Host { + const minimalMode: Plugin.__Host.EnabledStatusReporter = { + isEnabled: Services.Settings.getPluginMinimalModeEnabled, + events: new Emitter(), + } + MaskMessages.events.pluginMinimalModeChanged.on( + ([id, val]) => minimalMode.events.emit(val ? 'enabled' : 'disabled', id), + { signal }, + ) + + return { + signal, + minimalMode, + addI18NResource(plugin, resource) { + createI18NBundle(plugin, resource)(i18NextInstance) + }, + createContext, + } +} diff --git a/packages/mask/shared/plugin-infra/register.d.ts b/packages/mask/src/plugin-infra/register.d.ts similarity index 100% rename from packages/mask/shared/plugin-infra/register.d.ts rename to packages/mask/src/plugin-infra/register.d.ts diff --git a/packages/mask/src/plugin-infra/register.js b/packages/mask/src/plugin-infra/register.js new file mode 100644 index 000000000000..40e389058eeb --- /dev/null +++ b/packages/mask/src/plugin-infra/register.js @@ -0,0 +1,44 @@ +// This file is a JavaScript file because it's reference to the plugins should not be counted as a project reference. +// If your plugin also works in isolated dashboard, please also register it in +// packages/dashboard/src/initialization/plugins.ts +import '@masknet/plugin-example' +import '@masknet/plugin-debugger' +import '@masknet/plugin-flow' +import '@masknet/plugin-file-service' +import '@masknet/plugin-rss3' +import '@masknet/plugin-dao' +import '@masknet/plugin-solana' +import '@masknet/plugin-cyberconnect' +import '@masknet/plugin-go-plus-security' +import '@masknet/plugin-cross-chain-bridge' +import '@masknet/plugin-scamsniffer' +import '../plugins/Wallet' +import '@masknet/plugin-evm' +import '../plugins/RedPacket' +import '../plugins/ITO' +import '../plugins/Snapshot' +import '../plugins/Savings' +import '../plugins/Collectible' +import '../plugins/Transak' +import '../plugins/Gitcoin' +import '../plugins/VCent' +import '../plugins/Trader' +import '../plugins/Avatar' +import '../plugins/Furucombo' +import '../plugins/MaskBox' +import '../plugins/NextID' +import '../plugins/Pets' +import '../plugins/Game' +import '../plugins/CryptoartAI' +import '../plugins/FindTruman' +import '../plugins/ArtBlocks' +import '../plugins/Referral' +import '../plugins/Tips' +import '../plugins/Approval' +import '@masknet/plugin-web3-profile' +// import '../plugins/dHEDGE' +// import '../plugins/External' +// import '../plugins/Polls' +// import '../plugins/PoolTogether' +// import '../plugins/GoodGhosting' +// import '../plugins/UnlockProtocol' diff --git a/packages/mask/src/plugins/Wallet/services/account.ts b/packages/mask/src/plugins/Wallet/services/account.ts index 80b8f2325b61..e48f83445a68 100644 --- a/packages/mask/src/plugins/Wallet/services/account.ts +++ b/packages/mask/src/plugins/Wallet/services/account.ts @@ -5,7 +5,7 @@ import { currentMaskWalletAccountSettings, currentMaskWalletChainIdSettings, currentMaskWalletNetworkSettings, -} from '../../../../shared/legacy-settings/wallet-settings' +} from '../settings' import { Flags } from '../../../../shared' import { WalletRPC } from '../messages' import { defer, DeferTuple } from '@dimensiondev/kit' diff --git a/packages/mask/src/plugins/Wallet/services/wallet/database/wallet.ts b/packages/mask/src/plugins/Wallet/services/wallet/database/wallet.ts index a279e39f6d0f..f2627b2fd56c 100644 --- a/packages/mask/src/plugins/Wallet/services/wallet/database/wallet.ts +++ b/packages/mask/src/plugins/Wallet/services/wallet/database/wallet.ts @@ -4,7 +4,7 @@ import { WalletMessages } from '@masknet/plugin-wallet' import { asyncIteratorToArray } from '@masknet/shared-base' import { formatEthereumAddress, isValidAddress } from '@masknet/web3-shared-evm' import { PluginDB } from '../../../database/Plugin.db' -import { currentMaskWalletAccountSettings } from '../../../../../../shared/legacy-settings/wallet-settings' +import { currentMaskWalletAccountSettings } from '../../../settings' import type { WalletRecord } from '../type' function WalletRecordOutDB(record: WalletRecord) { diff --git a/packages/mask/src/plugins/Wallet/services/wallet/locker.ts b/packages/mask/src/plugins/Wallet/services/wallet/locker.ts index d5c83102b09a..278cb67af4c1 100644 --- a/packages/mask/src/plugins/Wallet/services/wallet/locker.ts +++ b/packages/mask/src/plugins/Wallet/services/wallet/locker.ts @@ -1,5 +1,6 @@ -import { currentMaskWalletLockStatusSettings, LockStatus } from '../../../../../shared/legacy-settings/wallet-settings' +import { currentMaskWalletLockStatusSettings } from '../../settings' import * as password from './password' +import { LockStatus } from '../../types' import { WalletMessages } from '../../messages' export async function isLocked() { diff --git a/packages/mask/shared/legacy-settings/wallet-settings.ts b/packages/mask/src/plugins/Wallet/settings.ts similarity index 74% rename from packages/mask/shared/legacy-settings/wallet-settings.ts rename to packages/mask/src/plugins/Wallet/settings.ts index d226caa62297..ab270d7872c0 100644 --- a/packages/mask/shared/legacy-settings/wallet-settings.ts +++ b/packages/mask/src/plugins/Wallet/settings.ts @@ -1,13 +1,7 @@ -import { PluginId } from '@masknet/plugin-infra' +import { createGlobalSettings } from '../../../shared/legacy-settings/createSettings' import { ChainId, NetworkType } from '@masknet/web3-shared-evm' -import { createGlobalSettings } from './createSettings' - -const PLUGIN_ID = PluginId.Wallet -export enum LockStatus { - INIT = 0, - UNLOCK = 1, - LOCKED = 2, -} +import { PLUGIN_ID } from './constants' +import { LockStatus } from './types' export const currentMaskWalletAccountSettings = createGlobalSettings(`${PLUGIN_ID}+selectedMaskWalletAddress`, '') diff --git a/packages/mask/src/plugins/Wallet/types/index.ts b/packages/mask/src/plugins/Wallet/types/index.ts new file mode 100644 index 000000000000..f20ad395c979 --- /dev/null +++ b/packages/mask/src/plugins/Wallet/types/index.ts @@ -0,0 +1,5 @@ +export enum LockStatus { + INIT = 0, + UNLOCK = 1, + LOCKED = 2, +} diff --git a/packages/mask/src/social-network/ui.ts b/packages/mask/src/social-network/ui.ts index a0810be747e6..f91f99839916 100644 --- a/packages/mask/src/social-network/ui.ts +++ b/packages/mask/src/social-network/ui.ts @@ -13,15 +13,14 @@ import { queryRemoteI18NBundle, } from '@masknet/shared-base' import { Environment, assertNotEnvironment, ValueRef } from '@dimensiondev/holoflows-kit' -import { IdentityResolved, Plugin, PluginId, startPluginSNSAdaptor } from '@masknet/plugin-infra/content-script' +import { IdentityResolved, PluginId, startPluginSNSAdaptor } from '@masknet/plugin-infra/content-script' import { getCurrentIdentifier, getCurrentSNSNetwork } from '../social-network-adaptor/utils' -import { createPluginHost, createPartialSharedUIContext } from '../../shared/plugin-infra/host' +import { createPluginHost, createSharedContext } from '../plugin-infra/host' import { definedSocialNetworkUIs } from './define' import { setupShadowRootPortal, MaskMessages } from '../utils' import { delay, waitDocumentReadyState } from '@dimensiondev/kit' import { sharedUINetworkIdentifier, sharedUIComponentOverwrite } from '@masknet/shared' import { SocialNetworkEnum } from '@masknet/encryption' -import { RestPartOfPluginUIContextShared } from '../utils/plugin-context-shared-ui' const definedSocialNetworkUIsResolved = new Map() export let activatedSocialNetworkUI: SocialNetworkUI.Definition = { @@ -113,47 +112,38 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI. }) signal.addEventListener('abort', queryRemoteI18NBundle(Services.Helper.queryRemoteI18NBundle)) - const allPersonaSub = createSubscriptionFromAsync( - () => { - console.log('DEBUG: currentPersonaIdentifier') - return Services.Identity.queryOwnedPersonaInformation(true) - }, - [], - MaskMessages.events.currentPersonaIdentifier.on, - signal, - ) - const empty = new ValueRef(undefined) - const lastRecognizedSub = createSubscriptionFromValueRef( - ui.collecting.identityProvider?.recognized || empty, - signal, - ) - const currentVisitingSub = createSubscriptionFromValueRef( - ui.collecting.currentVisitingIdentityProvider?.recognized || empty, - signal, - ) - startPluginSNSAdaptor( getCurrentSNSNetwork(ui.networkIdentifier), - createPluginHost( - signal, - (pluginID, signal): Plugin.SNSAdaptor.SNSAdaptorContext => { - return { - ...createPartialSharedUIContext(pluginID, signal), - ...RestPartOfPluginUIContextShared, - lastRecognizedProfile: lastRecognizedSub, - currentVisitingProfile: currentVisitingSub, - allPersonas: allPersonaSub, - privileged_silentSign: () => { - if (pluginID !== PluginId.Web3Profile) - throw new TypeError("current plugin doesn't support silent sign function") - return Services.Identity.generateSignResult - }, - getPersonaAvatar: Services.Identity.getPersonaAvatar, - ownProofChanged: MaskMessages.events.ownProofChanged, - } - }, - Services.Settings.getPluginMinimalModeEnabled, - ), + createPluginHost(signal, (pluginID, signal) => { + const empty = new ValueRef(undefined) + const lastRecognizedSub = createSubscriptionFromValueRef( + ui.collecting.identityProvider?.recognized || empty, + signal, + ) + const currentVisitingSub = createSubscriptionFromValueRef( + ui.collecting.currentVisitingIdentityProvider?.recognized || empty, + signal, + ) + const allPersonaSub = createSubscriptionFromAsync( + () => Services.Identity.queryOwnedPersonaInformation(true), + [], + MaskMessages.events.currentPersonaIdentifier.on, + signal, + ) + return { + ...createSharedContext(pluginID, signal), + lastRecognizedProfile: lastRecognizedSub, + currentVisitingProfile: currentVisitingSub, + allPersonas: allPersonaSub, + privileged_silentSign: () => { + if (pluginID !== PluginId.Web3Profile) + throw new TypeError("current plugin doesn't support silent sign function") + return Services.Identity.generateSignResult + }, + getPersonaAvatar: Services.Identity.getPersonaAvatar, + MaskMessages, + } + }), ) setupShadowRootPortal() diff --git a/packages/mask/src/tsconfig.json b/packages/mask/src/tsconfig.json index b46d44d5a0ba..fd9627fe22ca 100644 --- a/packages/mask/src/tsconfig.json +++ b/packages/mask/src/tsconfig.json @@ -8,6 +8,7 @@ "lib": ["ES2021"] }, "include": ["./", "./**/*.json"], + "exclude": ["./plugin-infra/register.js"], // ! Note: mask/ depends dashboard/ on source-code level // ! but dashboard/ depends mask/ on type level diff --git a/packages/mask/src/utils/plugin-context-shared-ui.ts b/packages/mask/src/utils/plugin-context-shared-ui.ts deleted file mode 100644 index 195471cab7da..000000000000 --- a/packages/mask/src/utils/plugin-context-shared-ui.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { WalletConnectQRCodeDialogEvent, WalletMessages } from '@masknet/plugin-wallet' -import { createSubscriptionFromAsync, EMPTY_LIST } from '@masknet/shared-base' -import Services from '../extension/service' -import { WalletRPC } from '../plugins/Wallet/messages' -import { MaskMessages } from './messages' - -export const RestPartOfPluginUIContextShared = { - currentPersona: createSubscriptionFromAsync( - Services.Settings.getCurrentPersonaIdentifier, - undefined, - MaskMessages.events.currentPersonaIdentifier.on, - ), - send: WalletRPC.sendPayload, - fetch: r2d2Fetch, - openPopupWindow: Services.Helper.openPopupWindow, - closePopupWindow: Services.Helper.removePopupWindow, - - openWalletConnectDialog: (uri: string, callback: () => void) => { - const onClose = (ev: WalletConnectQRCodeDialogEvent) => { - if (ev.open) return - callback() - WalletMessages.events.walletConnectQRCodeDialogUpdated.off(onClose) - } - WalletMessages.events.walletConnectQRCodeDialogUpdated.on(onClose) - WalletMessages.events.walletConnectQRCodeDialogUpdated.sendToLocal({ - open: true, - uri, - }) - }, - closeWalletConnectDialog: () => { - WalletMessages.events.walletConnectQRCodeDialogUpdated.sendToLocal({ - open: false, - }) - }, - - wallets: createSubscriptionFromAsync( - () => WalletRPC.getWallets(), - EMPTY_LIST, - WalletMessages.events.walletsUpdated.on, - ), - walletPrimary: createSubscriptionFromAsync( - () => WalletRPC.getWalletPrimary(), - null, - WalletMessages.events.walletsUpdated.on, - ), - - personaSignMessage: Services.Identity.signWithPersona, - - updateAccount: WalletRPC.updateMaskAccount, - resetAccount: WalletRPC.resetMaskAccount, - selectAccount: WalletRPC.selectMaskAccount, - - signTransaction: WalletRPC.signTransaction, - signTypedData: WalletRPC.signTypedData, - signPersonalMessage: WalletRPC.signPersonalMessage, - - getWallets: WalletRPC.getWallets, - getWalletPrimary: WalletRPC.getWalletPrimary, - addWallet: WalletRPC.updateWallet, - updateWallet: WalletRPC.updateWallet, - removeWallet: WalletRPC.removeWallet, -} diff --git a/packages/plugin-infra/src/types.ts b/packages/plugin-infra/src/types.ts index 25e40e1dea8d..de1241da56ee 100644 --- a/packages/plugin-infra/src/types.ts +++ b/packages/plugin-infra/src/types.ts @@ -11,6 +11,7 @@ import type { PopupRoutes, PersonaInformation, ECKeyIdentifier, + MaskEvents, } from '@masknet/shared-base' import type { ChainDescriptor, @@ -25,7 +26,7 @@ import type { import type { ChainId, SchemaType, Transaction } from '@masknet/web3-shared-evm' import type { Emitter } from '@servie/events' import type { Web3Plugin } from './web3-types' -import type { UnboundedRegistry } from '@dimensiondev/holoflows-kit' +import type { WebExtensionMessage } from '@dimensiondev/holoflows-kit' export declare namespace Plugin { /** @@ -134,8 +135,6 @@ export namespace Plugin.Shared { * A lightweight K/V storage used to store some simple data. */ createKVStorage(type: 'memory' | 'persistent', defaultValues: T): ScopedStorage - } - export interface SharedUIContext extends SharedContext { /** The selected account of Mask Wallet */ account: Subscription /** The selected chainId of Mask Wallet */ @@ -350,13 +349,13 @@ export namespace Plugin.Shared { /** This part runs in the SNSAdaptor */ export namespace Plugin.SNSAdaptor { - export interface SNSAdaptorContext extends Shared.SharedUIContext { + export interface SNSAdaptorContext extends Shared.SharedContext { lastRecognizedProfile: Subscription currentVisitingProfile: Subscription allPersonas?: Subscription privileged_silentSign: () => (signer: ECKeyIdentifier, message: string) => Promise getPersonaAvatar: (identifier: ECKeyIdentifier | null | undefined) => Promise - ownProofChanged: UnboundedRegistry + MaskMessages: WebExtensionMessage } export type SelectProviderDialogEvent = @@ -616,7 +615,7 @@ export namespace Plugin.SNSAdaptor { /** This part runs in the dashboard */ export namespace Plugin.Dashboard { - export interface DashboardContext extends Shared.SharedUIContext {} + export interface DashboardContext extends Shared.SharedContext {} // As you can see we currently don't have so much use case for an API here. export interface Definition< ChainId = unknown, diff --git a/packages/plugin-infra/src/web3-state/Connection.ts b/packages/plugin-infra/src/web3-state/Connection.ts index ee8d2710eda0..d560c06676bc 100644 --- a/packages/plugin-infra/src/web3-state/Connection.ts +++ b/packages/plugin-infra/src/web3-state/Connection.ts @@ -36,9 +36,9 @@ export class ConnectionState< > { constructor( - protected context: Plugin.Shared.SharedUIContext, + protected context: Plugin.Shared.SharedContext, protected createConnection: ( - context: Plugin.Shared.SharedUIContext, + context: Plugin.Shared.SharedContext, options?: { chainId?: ChainId account?: string diff --git a/packages/plugin-infra/src/web3-state/Provider.ts b/packages/plugin-infra/src/web3-state/Provider.ts index 3eb85a02c718..99b78fa517ee 100644 --- a/packages/plugin-infra/src/web3-state/Provider.ts +++ b/packages/plugin-infra/src/web3-state/Provider.ts @@ -34,7 +34,7 @@ export class ProviderState< public providerType?: Subscription constructor( - protected context: Plugin.Shared.SharedUIContext, + protected context: Plugin.Shared.SharedContext, protected providers: Record>, protected options: { isValidAddress(a?: string): boolean diff --git a/packages/plugin-infra/src/web3-state/Wallet.ts b/packages/plugin-infra/src/web3-state/Wallet.ts index f353b1d78191..1bde2f01d7a2 100644 --- a/packages/plugin-infra/src/web3-state/Wallet.ts +++ b/packages/plugin-infra/src/web3-state/Wallet.ts @@ -6,7 +6,7 @@ export class WalletState implements Web3WalletState { public wallets?: Subscription public walletPrimary?: Subscription - constructor(protected context: Plugin.Shared.SharedUIContext) { + constructor(protected context: Plugin.Shared.SharedContext) { this.wallets = context.wallets this.walletPrimary = context.walletPrimary } diff --git a/packages/plugins/EVM/src/settings/index.ts b/packages/plugins/EVM/src/settings/index.ts index c50aa37c5eae..fa91ea279624 100644 --- a/packages/plugins/EVM/src/settings/index.ts +++ b/packages/plugins/EVM/src/settings/index.ts @@ -3,4 +3,4 @@ import { createValueRefWithReady } from '@masknet/shared-base' import type { EVM_Web3State } from '../state/Connection/types' export const Web3StateSettings = createValueRefWithReady(null!) -export const SharedContextSettings = createValueRefWithReady(null!) +export const SharedContextSettings = createValueRefWithReady(null!) diff --git a/packages/plugins/EVM/src/state/Connection.ts b/packages/plugins/EVM/src/state/Connection.ts index 151616ede792..5bcd52f74150 100644 --- a/packages/plugins/EVM/src/state/Connection.ts +++ b/packages/plugins/EVM/src/state/Connection.ts @@ -30,7 +30,7 @@ export class Connection extends ConnectionState< Web3Provider > { constructor( - context: Plugin.Shared.SharedUIContext, + context: Plugin.Shared.SharedContext, subscription: { account?: Subscription chainId?: Subscription diff --git a/packages/plugins/EVM/src/state/Connection/connection.ts b/packages/plugins/EVM/src/state/Connection/connection.ts index 8fa3ce8c7cc0..40fc8f315420 100644 --- a/packages/plugins/EVM/src/state/Connection/connection.ts +++ b/packages/plugins/EVM/src/state/Connection/connection.ts @@ -105,7 +105,7 @@ class Connection implements EVM_Connection { private chainId: ChainId, private account: string, private providerType: ProviderType, - private context?: Plugin.Shared.SharedUIContext, + private context?: Plugin.Shared.SharedContext, ) {} // Hijack RPC requests and process them with koa like middleware @@ -979,7 +979,7 @@ class Connection implements EVM_Connection { * @returns */ export function createConnection( - context?: Plugin.Shared.SharedUIContext, + context?: Plugin.Shared.SharedContext, options?: { chainId?: ChainId account?: string diff --git a/packages/plugins/EVM/src/state/IdentityService.ts b/packages/plugins/EVM/src/state/IdentityService.ts index 6bddb8294bd3..c1d28b512d03 100644 --- a/packages/plugins/EVM/src/state/IdentityService.ts +++ b/packages/plugins/EVM/src/state/IdentityService.ts @@ -36,7 +36,7 @@ function getAddress(text: string) { } export class IdentityService extends IdentityServiceState { - constructor(protected context: Plugin.Shared.SharedUIContext) { + constructor(protected context: Plugin.Shared.SharedContext) { super() } diff --git a/packages/plugins/EVM/src/state/Provider.ts b/packages/plugins/EVM/src/state/Provider.ts index 39e20347f366..a2f3b496138f 100644 --- a/packages/plugins/EVM/src/state/Provider.ts +++ b/packages/plugins/EVM/src/state/Provider.ts @@ -16,7 +16,7 @@ import { ExtensionSite, mapSubscription, mergeSubscription } from '@masknet/shar import { getEnumAsArray } from '@dimensiondev/kit' export class Provider extends ProviderState { - constructor(context: Plugin.Shared.SharedUIContext) { + constructor(context: Plugin.Shared.SharedContext) { super(context, Providers, { isSameAddress, isValidAddress, diff --git a/packages/plugins/EVM/src/state/Wallet.ts b/packages/plugins/EVM/src/state/Wallet.ts index b82548768d01..06f227b0042e 100644 --- a/packages/plugins/EVM/src/state/Wallet.ts +++ b/packages/plugins/EVM/src/state/Wallet.ts @@ -2,7 +2,7 @@ import type { Plugin } from '@masknet/plugin-infra' import { WalletState } from '@masknet/plugin-infra/web3' export class Wallet extends WalletState { - constructor(context: Plugin.Shared.SharedUIContext) { + constructor(context: Plugin.Shared.SharedContext) { super(context) } } diff --git a/packages/plugins/EVM/src/state/index.ts b/packages/plugins/EVM/src/state/index.ts index 943adffd5ec0..e40147fa2eee 100644 --- a/packages/plugins/EVM/src/state/index.ts +++ b/packages/plugins/EVM/src/state/index.ts @@ -17,7 +17,7 @@ import { IdentityService } from './IdentityService' import { BalanceNotifier } from './BalanceNotifier' import { BlockNumberNotifier } from './BlockNumberNotifier' -export function createWeb3State(context: Plugin.Shared.SharedUIContext): EVM_Web3State { +export function createWeb3State(context: Plugin.Shared.SharedContext): EVM_Web3State { const Provider_ = new Provider(context) const Settings_ = new Settings(context) const Transaction_ = new Transaction(context, { diff --git a/packages/plugins/Flow/src/state/Connection.ts b/packages/plugins/Flow/src/state/Connection.ts index 3c9006bb1799..7ad463e42491 100644 --- a/packages/plugins/Flow/src/state/Connection.ts +++ b/packages/plugins/Flow/src/state/Connection.ts @@ -34,7 +34,7 @@ export class Connection extends ConnectionState< Web3Provider > { constructor( - context: Plugin.Shared.SharedUIContext, + context: Plugin.Shared.SharedContext, subscription: { account?: Subscription chainId?: Subscription diff --git a/packages/plugins/Flow/src/state/Provider.ts b/packages/plugins/Flow/src/state/Provider.ts index 6adbe59e3777..fba79c7ca576 100644 --- a/packages/plugins/Flow/src/state/Provider.ts +++ b/packages/plugins/Flow/src/state/Provider.ts @@ -14,7 +14,7 @@ import { import { Providers } from './Connection/provider' export class Provider extends ProviderState { - constructor(override context: Plugin.Shared.SharedUIContext) { + constructor(override context: Plugin.Shared.SharedContext) { super(context, Providers, { isSameAddress, isValidChainId, diff --git a/packages/plugins/Flow/src/state/Wallet.ts b/packages/plugins/Flow/src/state/Wallet.ts index 7930e118270c..8ea5558b3f13 100644 --- a/packages/plugins/Flow/src/state/Wallet.ts +++ b/packages/plugins/Flow/src/state/Wallet.ts @@ -2,7 +2,7 @@ import type { Plugin } from '@masknet/plugin-infra' import { WalletState } from '@masknet/plugin-infra/web3' export class Wallet extends WalletState { - constructor(override context: Plugin.Shared.SharedUIContext) { + constructor(override context: Plugin.Shared.SharedContext) { super(context) } } diff --git a/packages/plugins/Flow/src/state/index.ts b/packages/plugins/Flow/src/state/index.ts index 3abcca152fab..14dc81a61f89 100644 --- a/packages/plugins/Flow/src/state/index.ts +++ b/packages/plugins/Flow/src/state/index.ts @@ -10,7 +10,7 @@ import { Others } from './Others' import type { FlowWeb3State } from './Connection/types' import { IdentityService } from './IdentityService' -export function createWeb3State(context: Plugin.Shared.SharedUIContext): FlowWeb3State { +export function createWeb3State(context: Plugin.Shared.SharedContext): FlowWeb3State { const Provider_ = new Provider(context) return { AddressBook: new AddressBook(context, { diff --git a/packages/plugins/Solana/src/state/Connection.ts b/packages/plugins/Solana/src/state/Connection.ts index 99e10b0e1ec0..eb3c156f202d 100644 --- a/packages/plugins/Solana/src/state/Connection.ts +++ b/packages/plugins/Solana/src/state/Connection.ts @@ -30,7 +30,7 @@ export class Connection extends ConnectionState< Web3Provider > { constructor( - context: Plugin.Shared.SharedUIContext, + context: Plugin.Shared.SharedContext, subscription: { account?: Subscription chainId?: Subscription diff --git a/packages/plugins/Solana/src/state/Provider.ts b/packages/plugins/Solana/src/state/Provider.ts index c382eb4d92ac..55df390aba3d 100644 --- a/packages/plugins/Solana/src/state/Provider.ts +++ b/packages/plugins/Solana/src/state/Provider.ts @@ -14,7 +14,7 @@ import { import { Providers } from './Connection/provider' export class Provider extends ProviderState { - constructor(override context: Plugin.Shared.SharedUIContext) { + constructor(override context: Plugin.Shared.SharedContext) { super(context, Providers, { isSameAddress, isValidChainId, diff --git a/packages/plugins/Solana/src/state/Wallet.ts b/packages/plugins/Solana/src/state/Wallet.ts index 7930e118270c..8ea5558b3f13 100644 --- a/packages/plugins/Solana/src/state/Wallet.ts +++ b/packages/plugins/Solana/src/state/Wallet.ts @@ -2,7 +2,7 @@ import type { Plugin } from '@masknet/plugin-infra' import { WalletState } from '@masknet/plugin-infra/web3' export class Wallet extends WalletState { - constructor(override context: Plugin.Shared.SharedUIContext) { + constructor(override context: Plugin.Shared.SharedContext) { super(context) } } diff --git a/packages/plugins/Solana/src/state/index.ts b/packages/plugins/Solana/src/state/index.ts index 16b887b52e8f..82cd52219309 100644 --- a/packages/plugins/Solana/src/state/index.ts +++ b/packages/plugins/Solana/src/state/index.ts @@ -11,7 +11,7 @@ import type { SolanaWeb3State } from './Connection/types' import { IdentityService } from './IdentityService' import { NameService } from './NameService' -export function createWeb3State(context: Plugin.Shared.SharedUIContext): SolanaWeb3State { +export function createWeb3State(context: Plugin.Shared.SharedContext): SolanaWeb3State { const Provider_ = new Provider(context) const Settings_ = new Settings(context) diff --git a/packages/plugins/Web3Profile/src/SNSAdaptor/components/Web3ProfileDialog.tsx b/packages/plugins/Web3Profile/src/SNSAdaptor/components/Web3ProfileDialog.tsx index cbc3a7018731..2bb81a3d7667 100644 --- a/packages/plugins/Web3Profile/src/SNSAdaptor/components/Web3ProfileDialog.tsx +++ b/packages/plugins/Web3Profile/src/SNSAdaptor/components/Web3ProfileDialog.tsx @@ -83,7 +83,11 @@ export function Web3ProfileDialog() { if (!currentPersona) return return NextIDProof.queryExistedBindingByPersona(currentPersona.identifier.publicKeyAsHex!) }, [currentPersona]) - useEffect(() => context?.ownProofChanged.on(retryQueryBinding), [retryQueryBinding]) + useEffect(() => { + return context?.MaskMessages.events.ownProofChanged.on(() => { + retryQueryBinding() + }) + }, [retryQueryBinding]) const wallets = bindings?.proofs diff --git a/packages/scripts/src/commands/new-package.ts b/packages/scripts/src/commands/new-package.ts index 40ec63b844ac..bd9f5bb0794d 100644 --- a/packages/scripts/src/commands/new-package.ts +++ b/packages/scripts/src/commands/new-package.ts @@ -104,7 +104,7 @@ async function createNewPackage({ path, npmName, type, pluginID }: PackageOption * .i18n-codegen.json * packages/plugins/tsconfig.json * packages/plugin-infra/src/types.ts - * packages/mask/shared/plugin-infra/register.ts + * packages/mask/src/plugin-infra/register.ts * packages/mask/package.json */ await changeFile.JSON(resolve(ROOT_PATH, '.i18n-codegen.json'), (content) => { @@ -127,7 +127,7 @@ async function createNewPackage({ path, npmName, type, pluginID }: PackageOption content.replace(INSERT_HERE, `${NormativeName} = '${pluginID}'\n${INSERT_HERE}`), ) await changeFile.typescript( - resolve(ROOT_PATH, `packages/mask/shared/plugin-infra/register.js`), + resolve(ROOT_PATH, `packages/mask/src/plugin-infra/register.js`), (content) => `${content}import '${npmName}'`, ) await awaitChildProcess(shell.cwd(ROOT_PATH)`pnpm install --prefer-offline -C packages/mask ${npmName}`) diff --git a/packages/shared-base/src/serializer/index.ts b/packages/shared-base/src/serializer/index.ts index 5369e48c03f4..8912bbb51062 100644 --- a/packages/shared-base/src/serializer/index.ts +++ b/packages/shared-base/src/serializer/index.ts @@ -15,7 +15,7 @@ let typeson: Typeson | undefined function setup() { const { default: BigNumber } = BN // https://github.com/dfahlander/typeson-registry/issues/27 - typeson = new Typeson({ cyclic: false, sync: false }) + typeson = new Typeson({ cyclic: false }) typeson.register(builtin) typeson.register(specialNumbers) typeson.register([blob, file, filelist, imagebitmap]) diff --git a/packages/shared-base/src/serializer/typeson.d.ts b/packages/shared-base/src/serializer/typeson.d.ts index ff0175b157a1..b4c2fab74117 100644 --- a/packages/shared-base/src/serializer/typeson.d.ts +++ b/packages/shared-base/src/serializer/typeson.d.ts @@ -12,8 +12,8 @@ declare module 'typeson' { constructor(options?: { cyclic?: boolean encapsulateObserver?: (...args: unknown[]) => void - sync?: boolean - throwOnBadSyncType?: boolean + sync?: true + throwOnBadSyncType?: true }) register(register: unknown[] | Record | NewableFunction>): Typeson encapsulate(data: unknown): any diff --git a/packages/theme/src/Components/Alert/index.tsx b/packages/theme/src/Components/Alert/index.tsx index 0cc887b85730..33477734e66b 100644 --- a/packages/theme/src/Components/Alert/index.tsx +++ b/packages/theme/src/Components/Alert/index.tsx @@ -35,14 +35,13 @@ const useStyles = makeStyles()((theme) => ({ export interface MaskAlertProps extends AlertProps {} -export const MaskAlert = forwardRef((props, ref) => { +export const MaskAlert = forwardRef((props: MaskAlertProps) => { const { children, ...rest } = props const { classes } = useStyles() return (