Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"juicebox",
"kdfparams",
"keccak",
"keybase",
"kitts",
"kred",
"labelledby",
Expand Down
6 changes: 5 additions & 1 deletion packages/mask/background/database/persona/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type {
AESJsonWebKey as Native_AESJsonWebKey,
} from '@masknet/public-api'
import { MaskMessages } from '../../../shared'
import { convertPersonaHexPublicKey } from './util'
export async function consistentPersonaDBWriteAccess(action: () => Promise<void>) {
await action()
}
Expand Down Expand Up @@ -392,11 +393,14 @@ function partialPersonaRecordToDB(
}

function personaRecordOutDB(x: NativePersonaRecord): PersonaRecord {
const identifier = Identifier.fromString(x.identifier, ECKeyIdentifier).unwrap()

return {
publicKey: x.publicKey as JsonWebKey as unknown as EC_Public_JsonWebKey,
publicHexKey: convertPersonaHexPublicKey(identifier),
privateKey: x.privateKey as JsonWebKey as unknown as EC_Private_JsonWebKey,
localKey: x.localKey as JsonWebKey as unknown as AESJsonWebKey,
identifier: Identifier.fromString(x.identifier, ECKeyIdentifier).unwrap(),
identifier,
linkedProfiles: new IdentifierMap(new Map(Object.entries(x.linkedProfiles)), ProfileIdentifier),
createdAt: new Date(x.createdAt),
updatedAt: new Date(x.updatedAt),
Expand Down
1 change: 1 addition & 0 deletions packages/mask/background/database/persona/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export interface PersonaRecord {
parameter: { path: string; withPassword: boolean }
}
publicKey: EC_Public_JsonWebKey
publicHexKey?: string
privateKey?: EC_Private_JsonWebKey
localKey?: AESJsonWebKey
nickname?: string
Expand Down
9 changes: 9 additions & 0 deletions packages/mask/background/database/persona/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { compressSecp256k1Point, decompressSecp256k1Key, PersonaIdentifier, toHex } from '@masknet/shared-base'

export function convertPersonaHexPublicKey(persona: PersonaIdentifier) {
const key256 = decompressSecp256k1Key(persona.compressedPoint.replace(/\|/g, '/'))
if (!key256.x || !key256.y) return
const arr = compressSecp256k1Point(key256.x, key256.y)

return `0x${toHex(arr)}`
}
6 changes: 5 additions & 1 deletion packages/mask/background/database/persona/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type {
PersonaRecord,
} from './type'
import { isEmpty } from 'lodash-unified'
import { convertPersonaHexPublicKey } from './util'
/**
* Database structure:
*
Expand Down Expand Up @@ -701,9 +702,12 @@ function personaRecordToDB(x: PersonaRecord): PersonaRecordDB {
function personaRecordOutDB(x: PersonaRecordDB): PersonaRecord {
// @ts-ignore
delete x.hasPrivateKey
const identifier = Identifier.fromString(x.identifier, ECKeyIdentifier).unwrap()

const obj: PersonaRecord = {
...x,
identifier: Identifier.fromString(x.identifier, ECKeyIdentifier).unwrap(),
identifier,
publicHexKey: convertPersonaHexPublicKey(identifier),
linkedProfiles: new IdentifierMap(x.linkedProfiles, ProfileIdentifier),
}
return obj
Expand Down
2 changes: 2 additions & 0 deletions packages/mask/background/services/helper/nextID.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ async function queryPersonaHexPublicKey(persona: PersonaIdentifier) {
return `0x${toHex(arr)}`
}

/** @deprecated Use NextIDService */
export async function queryExistedBinding(persona: PersonaIdentifier) {
const publicKey = await queryPersonaHexPublicKey(persona)
if (!publicKey) return
Expand All @@ -92,6 +93,7 @@ export async function queryExistedBinding(persona: PersonaIdentifier) {
return first(result.ids)
}

/** @deprecated Use NextIDService */
export async function createPersonaPayload(
persona: PersonaIdentifier,
action: 'create' | 'delete',
Expand Down
19 changes: 13 additions & 6 deletions packages/mask/shared-ui/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,22 @@
"setup_guide_find_username_text": "Mask needs the username to connect your profile to your persona.",
"setup_guide_connect_auto": "Connect",
"setup_guide_connect_failed": "Re-Connect",
"setup_guide_verify": "Verfiy",
"setup_guide_verify_dismiss": "Don't show again.",
"setup_guide_verify_checking": "Checking",
"setup_guide_verify_post_not_found": "No verification post found",
"setup_guide_verifying": "Verfiying",
"setup_guide_verifying_failed": "Re-Verfiy",
"user_guide_tip_connected": "You have connected to this account successfully.",
"user_guide_tip_need_verify_on_next_id": "Mask Network requires you to post an verification tweet to access Next.ID-based products.",
"setup_guide_say_hello_content": "Hello Mask world. This is my first encrypted message. Install https://mask.io to send me encrypted post. ",
"setup_guide_say_hello_follow": "Follow {{account}} to explore Web 3.0.",
"setup_guide_pin_tip_0": "Don't forget to pin Mask Network in your browser toolbar to access web 3.0 easily.",
"setup_guide_pin_tip_1": "Click on ",
"setup_guide_pin_tip_1_s": " at top right of your browser.",
"setup_guide_pin_tip_2": "Find Mask Network in the list of extensions and click the ",
"setup_guide_pin_tip_2_s": " button.",
"setup_guide_pin_tip_3": "Pinned successfully.",
"setup_guide_pin_tip": "Don't forget to pin Mask Network in your browser toolbar to access web 3.0 easily.",
"setup_guide_pin_tip_step_click_left": "Click on ",
"setup_guide_pin_tip_step_click_right": " at top right of your browser.",
"setup_guide_pin_tip_step_find_left": "Find Mask Network in the list of extensions and click the ",
"setup_guide_pin_tip_step_find_right": " button.",
"setup_guide_pin_tip_successfully": "Pinned successfully.",
"setup_guide_pin_dismiss": "Don't show again.",
"user_guide_tip_1": "Connect wallet to explore multi-chain dApps.",
"user_guide_tip_2": "Setup your exclusive NFT Avatar, explore the endless possibilities of Web 3.0.",
Expand Down
73 changes: 73 additions & 0 deletions packages/mask/src/components/DataSource/useNextID.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { useAsync, useAsyncRetry } from 'react-use'
import type { NextIDPlatform } from '@masknet/shared-base'
import Services from '../../extension/service'
import { useMemo, useState } from 'react'
import { activatedSocialNetworkUI } from '../../social-network'
import { usePersonaConnectStatus } from './usePersonaConnectStatus'
import { currentSetupGuideStatus, dismissVerifyNextID } from '../../settings/settings'
import stringify from 'json-stable-stringify'
import { SetupGuideStep } from '../InjectedComponents/SetupGuide/types'
import type { SetupGuideCrossContextStatus } from '../../settings/types'
import { useLastRecognizedIdentity } from './useActivatedUI'
import { useValueRef } from '@masknet/shared'
import { queryExistedBindingByPersona, queryExistedBindingByPlatform, queryIsBound } from '@masknet/web3-providers'

export const usePersonaBoundPlatform = (personaPublicKey: string) => {
useAsyncRetry(() => {
return queryExistedBindingByPersona(personaPublicKey)
}, [personaPublicKey])
}

let isOpenedVerifyDialog = false

export const useNextIDBoundByPlatform = (platform: NextIDPlatform, identity: string) => {
useAsyncRetry(() => {
return queryExistedBindingByPlatform(platform, identity)
}, [platform, identity])
}

export function useNextIDConnectStatus() {
const ui = activatedSocialNetworkUI

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this alias?

const [enableNextID] = useState(ui.configuration.nextIDConfig?.enable)
const personaConnectStatus = usePersonaConnectStatus()
const lastStateRef = currentSetupGuideStatus[ui.networkIdentifier]
const lastState_ = useValueRef(lastStateRef)
const lastState = useMemo<SetupGuideCrossContextStatus>(() => {
try {
return JSON.parse(lastState_)
} catch {
return {}
}
}, [lastState_])

const lastRecognized = useLastRecognizedIdentity()
const [username] = useState(
lastState.username || (lastRecognized.identifier.isUnknown ? '' : lastRecognized.identifier.userId),
)

const { value: isVerified = false } = useAsync(async () => {
if (isOpenedVerifyDialog) return true
if (!enableNextID || !username || !personaConnectStatus.connected) return true

const currentPersona = await Services.Settings.getCurrentPersona()
if (!currentPersona?.publicHexKey) return true

if (dismissVerifyNextID[ui.networkIdentifier].value[`${username}_${currentPersona.identifier.toText()}`])
return true

const platform = ui.configuration.nextIDConfig?.platform as NextIDPlatform | undefined
if (!platform) return true

const isBound = await queryIsBound(currentPersona.publicHexKey, platform, username)
if (isBound) return true

currentSetupGuideStatus[ui.networkIdentifier].value = stringify({
status: SetupGuideStep.VerifyOnNextID,
persona: currentPersona?.identifier.toText(),
})
isOpenedVerifyDialog = true
return false
}, [username, enableNextID, lastStateRef.value])

return isVerified
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useMemo } from 'react'
import Services from '../../extension/service'
import { currentSetupGuideStatus } from '../../settings/settings'
import { activatedSocialNetworkUI } from '../../social-network'
import { SetupGuideStep } from '../InjectedComponents/SetupGuide'
import { SetupGuideStep } from '../InjectedComponents/SetupGuide/types'
import { useLastRecognizedIdentity } from './useActivatedUI'
import { useMyPersonas } from './useMyPersonas'

Expand Down
Loading