diff --git a/packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts b/packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts new file mode 100644 index 000000000000..5f0d53bef240 --- /dev/null +++ b/packages/mask/background/tasks/Cancellable/NotificationsToMobile.ts @@ -0,0 +1,10 @@ +import { notify } from 'async-call-rpc/full' +import { MaskMessages } from '../../../shared' +import { nativeAPI, hasNativeAPI } from '../../../shared/native-rpc' +export default function NotificationsToMobile(signal: AbortSignal) { + if (!hasNativeAPI) return + + // we don't need response + const forwardToMobile = notify(nativeAPI!.api.notify_visible_detected_profile_changed) + MaskMessages.events.Native_visibleSNS_currentDetectedProfileUpdated.on(forwardToMobile, { signal }) +} diff --git a/packages/mask/background/tasks/setup.hmr.ts b/packages/mask/background/tasks/setup.hmr.ts index c272019430d5..50ae02834047 100644 --- a/packages/mask/background/tasks/setup.hmr.ts +++ b/packages/mask/background/tasks/setup.hmr.ts @@ -3,6 +3,7 @@ import * as InjectContentScript from './Cancellable/InjectContentScripts' import * as InjectContentScriptMV3 from './Cancellable/InjectContentScripts-mv3' import * as IsolatedDashboardBridge from './Cancellable/IsolatedDashboardBridge' import * as CleanupProfileDatabase from './Cancellable/CleanProfileAndAvatar' +import * as NotificationsToMobile from './Cancellable/NotificationsToMobile' type CancelableJob = { default: (signal: AbortSignal) => void } const CancelableJobs: CancelableJob[] = [ @@ -10,6 +11,7 @@ const CancelableJobs: CancelableJob[] = [ process.env.manifest === '2' ? InjectContentScript : InjectContentScriptMV3, IsolatedDashboardBridge, CleanupProfileDatabase, + NotificationsToMobile, ] const abort = new AbortController() diff --git a/packages/mask/src/social-network/ui.ts b/packages/mask/src/social-network/ui.ts index f90b55fbbe35..f00be8ef66cd 100644 --- a/packages/mask/src/social-network/ui.ts +++ b/packages/mask/src/social-network/ui.ts @@ -128,8 +128,18 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI. function $unknownIdentityResolution() { const provider = ui.collecting.identityProvider - provider?.start(signal) - if (provider?.hasDeprecatedPlaceholderName) { + if (!provider) return + provider.start(signal) + provider.recognized.addListener((newValue, oldValue) => { + if (document.visibilityState === 'hidden') return + if (newValue.identifier.equals(oldValue.identifier)) return + if (newValue.identifier.isUnknown) return + + MaskMessages.events.Native_visibleSNS_currentDetectedProfileUpdated.sendToBackgroundPage( + newValue.identifier.toText(), + ) + }) + if (provider.hasDeprecatedPlaceholderName) { provider.recognized.addListener((id) => { if (signal.aborted) return if (id.identifier.isUnknown) return diff --git a/packages/mask/src/utils/native-rpc/Web.ts b/packages/mask/src/utils/native-rpc/Web.ts index 5710a140a93e..99de4f155aca 100644 --- a/packages/mask/src/utils/native-rpc/Web.ts +++ b/packages/mask/src/utils/native-rpc/Web.ts @@ -289,10 +289,6 @@ export const MaskNetworkAPI: MaskNetworkAPIs = { updatedAt: x.updatedAt.getTime(), })) }, - async SNSAdaptor_getCurrentDetectedProfile() { - const { activatedSocialNetworkUI } = await import('../../social-network') - return activatedSocialNetworkUI.collecting.identityProvider?.recognized.value.identifier.toText() - }, get_all_indexedDB_records: async () => { const personas = await Services.Identity.queryPersonaRecordsFromIndexedDB() const profiles = await Services.Identity.queryProfileRecordFromIndexedDB() diff --git a/packages/public-api/src/mobile.ts b/packages/public-api/src/mobile.ts index 4336502538c9..aa6f4804141e 100644 --- a/packages/public-api/src/mobile.ts +++ b/packages/public-api/src/mobile.ts @@ -8,6 +8,7 @@ import type { RelationRecord, PostRecord, } from './types' +import type { ProfileIdentifier_string } from './web' /** * APIs that both Android and iOS implements and have the same API signature @@ -112,6 +113,7 @@ export interface SharedNativeAPIs { pageOption?: PageOption }): Promise update_post(params: { post: Partial; options: { mode: 0 | 1 } }): Promise + notify_visible_detected_profile_changed(newID: ProfileIdentifier_string): Promise } /** * APIs that only implemented by iOS Mask Network diff --git a/packages/public-api/src/types/index.ts b/packages/public-api/src/types/index.ts index 6eeb8c317c3d..318044d3afe3 100644 --- a/packages/public-api/src/types/index.ts +++ b/packages/public-api/src/types/index.ts @@ -17,6 +17,31 @@ export interface LinkedProfileDetails { } // These type MUST be sync with packages/shared-base/src/crypto/JWKType +export interface JsonWebKey { + alg?: string + crv?: string + d?: string + dp?: string + dq?: string + e?: string + ext?: boolean + k?: string + key_ops?: string[] + kty?: string + n?: string + oth?: RsaOtherPrimesInfo[] + p?: string + q?: string + qi?: string + use?: string + x?: string + y?: string +} +export interface RsaOtherPrimesInfo { + d?: string + r?: string + t?: string +} export interface EC_Public_JsonWebKey extends JsonWebKey, Nominal<'EC public'> {} export interface EC_Private_JsonWebKey extends JsonWebKey, Nominal<'EC private'> {} export interface AESJsonWebKey extends JsonWebKey, Nominal<'AES'> {} diff --git a/packages/public-api/src/web.ts b/packages/public-api/src/web.ts index d507b9b8c2b6..fb4d55ad81ed 100644 --- a/packages/public-api/src/web.ts +++ b/packages/public-api/src/web.ts @@ -6,8 +6,8 @@ import type { PersonaRecord, ProfileRecord, RelationFavor, RelationRecord } from * Methods starts with "SNSAdaptor_" can only be called in SNS Adaptor. * Other methods can only be called in the background page. */ -type ProfileIdentifier_string = string -type PersonaIdentifier_string = string +export type ProfileIdentifier_string = string +export type PersonaIdentifier_string = string export interface MaskNetworkAPIs { app_suspended(): Promise app_resume(): Promise @@ -79,7 +79,6 @@ export interface MaskNetworkAPIs { wallet_updateEthereumAccount(params: { account: string }): Promise wallet_updateEthereumChainId(params: { chainId: number }): Promise wallet_getLegacyWalletInfo(): Promise - SNSAdaptor_getCurrentDetectedProfile(): Promise get_all_indexedDB_records(): Promise<{ personas: PersonaRecord[] profiles: ProfileRecord[] diff --git a/packages/public-api/tsconfig.json b/packages/public-api/tsconfig.json index 79cc5a5ace48..075f17e485aa 100644 --- a/packages/public-api/tsconfig.json +++ b/packages/public-api/tsconfig.json @@ -3,7 +3,9 @@ "compilerOptions": { "rootDir": "./src/", "outDir": "./dist/", - "tsBuildInfoFile": "./dist/.tsbuildinfo" + "tsBuildInfoFile": "./dist/.tsbuildinfo", + // NOT including web or node. + "types": [] }, "include": ["./src"], // This package MUST NOT use any other package. diff --git a/packages/shared-base/src/Messages/Mask.ts b/packages/shared-base/src/Messages/Mask.ts index 8d7a3839406f..b3d5fc4b1237 100644 --- a/packages/shared-base/src/Messages/Mask.ts +++ b/packages/shared-base/src/Messages/Mask.ts @@ -43,6 +43,7 @@ export interface MaskSNSEvents { NFTAvatarUpdated: NFTAvatarEvent NFTAvatarTimelineUpdated: NFTAvatarEvent nftAvatarSettingDialogUpdated: NFTAvatarSettingDialogEvent + Native_visibleSNS_currentDetectedProfileUpdated: string } export interface MaskEvents extends MaskSettingsEvents, MaskMobileOnlyEvents, MaskSNSEvents {