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
2 changes: 1 addition & 1 deletion packages/mask/background/services/identity/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { createPersonaByPrivateKey } from './persona/create'
export { signWithPersona, type SignRequest, type SignRequestResult } from './persona/sign'
export { signWithPersona, type SignRequest, type SignRequestResult, generateSignResult } from './persona/sign'
export { exportPersonaMnemonicWords, exportPersonaPrivateKey } from './persona/backup'
6 changes: 5 additions & 1 deletion packages/mask/background/services/identity/persona/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ECDSASignature,
} from 'ethereumjs-util'
import { MaskMessages } from '../../../../shared'
import { PersonaIdentifier, fromBase64URL, PopupRoutes } from '@masknet/shared-base'
import { PersonaIdentifier, fromBase64URL, PopupRoutes, ECKeyIdentifier } from '@masknet/shared-base'
import { queryPersonasWithPrivateKey } from '../../../../background/database/persona/db'
import { openPopupWindow } from '../../../../background/services/helper'
import { delay } from '@dimensiondev/kit'
Expand Down Expand Up @@ -49,6 +49,10 @@ export async function signWithPersona({ message, method, identifier }: SignReque
})
})
const signer = await waitForApprove
return generateSignResult(signer, message)
}

export async function generateSignResult(signer: ECKeyIdentifier, message: string) {
const persona = (await queryPersonasWithPrivateKey()).find((x) => x.identifier.equals(signer))
if (!persona) throw new Error('Persona not found')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import {
ProfileRecord,
LinkedProfileDetails,
RelationRecord,
detachProfileDB,
} from '../../../background/database/persona/db'
import {
queryPersonasDB as queryPersonasFromIndexedDB,
Expand Down Expand Up @@ -396,10 +395,8 @@ export async function queryPersonaByPrivateKey(privateKeyString: string) {
// #endregion

export async function detachProfileWithNextID(
profile: ProfileIdentifier,
uuid: string,
personaPublicKey: string,
action: NextIDAction,
platform: string,
identity: string,
createdAt: string,
Expand All @@ -412,6 +409,5 @@ export async function detachProfileWithNextID(
await bindProof(uuid, personaPublicKey, NextIDAction.Delete, platform, identity, createdAt, {
signature: options?.signature,
})
await detachProfileDB(profile)
MaskMessages.events.ownProofChanged.sendToAll(undefined)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { useNavigate, useLocation } from 'react-router-dom'
import { ECKeyIdentifier, Identifier, PopupRoutes } from '@masknet/shared-base'
import { useMyPersonas } from '../../../../../components/DataSource/useMyPersonas'
import type { Persona } from '../../../../../database'
import { delay } from '@dimensiondev/kit'
import { PersonaContext } from '../hooks/usePersonaContext'
import { MethodAfterPersonaSign } from '../../Wallet/type'
import { useAsyncFn } from 'react-use'
import Services from '../../../../service'

const useStyles = makeStyles()(() => ({
container: {
Expand Down Expand Up @@ -86,7 +89,7 @@ const PersonaSignRequest = memo(() => {
const [message, setMessage] = useState<string>()
const [selected, setSelected] = useState<Persona>()
const personas = useMyPersonas()

const { currentPersona } = PersonaContext.useContainer()
useEffect(() => {
if (!personas.length) return
const url = new URLSearchParams(location.search)
Expand All @@ -104,25 +107,72 @@ const PersonaSignRequest = memo(() => {
}
}, [personas, location.search])

const onSign = async () => {
const [, onSign] = useAsyncFn(async () => {
const url = new URLSearchParams(location.search)
if (!requestID || !selected) return
const selectedPersona = Identifier.fromString<ECKeyIdentifier>(
selected.identifier.toText(),
ECKeyIdentifier,
).unwrap()
MaskMessages.events.personaSignRequest.sendToBackgroundPage({
requestID,
selectedPersona: Identifier.fromString<ECKeyIdentifier>(
selected.identifier.toText(),
ECKeyIdentifier,
).unwrap(),
selectedPersona,
})

await delay(200)
window.close()
}
const method = url.get('method') as MethodAfterPersonaSign | undefined

if (!method) {
window.close()
return
}

// sign request from popup
switch (method) {
case MethodAfterPersonaSign.DISCONNECT_NEXT_ID:
if (!message) break
const signatureResult = await Services.Identity.generateSignResult(selectedPersona, message)

const profileIdentifier = url.get('profileIdentifier')
const platform = url.get('platform')
const identity = url.get('identity')
const createdAt = url.get('createdAt')
const uuid = url.get('uuid')

if (
!signatureResult ||
!profileIdentifier ||
!platform ||
!identity ||
!createdAt ||
!uuid ||
!currentPersona?.publicHexKey
)
break
await Services.Identity.detachProfileWithNextID(
uuid,
currentPersona.publicHexKey,
platform,
identity,
createdAt,
{
signature: signatureResult.signature.signature,
},
)
const profile = currentPersona.linkedProfiles.find((x) => x.identifier.toText() === profileIdentifier)
if (!profile) break
await Services.Identity.detachProfile(profile.identifier)
break
}
navigate(-1)
}, [location, selected, requestID, message, currentPersona])

const onCancel = async () => {
if (!requestID) return
const url = new URLSearchParams(location.search)
MaskMessages.events.personaSignRequest.sendToBackgroundPage({ requestID })
await delay(200)
window.close()
const method = url.get('method')
if (!method) window.close()
navigate(-1)
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ import {
EnhanceableSite,
NextIDAction,
NextIDPlatform,
PopupRoutes,
} from '@masknet/shared-base'
import { compact } from 'lodash-unified'
import { makeStyles } from '@masknet/theme'
import { useI18N, MaskMessages } from '../../../../../../utils'
import { useI18N } from '../../../../../../utils'
import { PersonaContext } from '../../hooks/usePersonaContext'
import { useAsyncFn, useAsyncRetry } from 'react-use'
import Services from '../../../../../service'
import { GrayMasks } from '@masknet/icons'
import { DisconnectDialog } from '../DisconnectDialog'
import { createPersonaPayload, queryExistedBindingByPersona } from '@masknet/web3-providers'
import { delay } from '@dimensiondev/kit'
import classNames from 'classnames'
import { useNavigate } from 'react-router-dom'
import urlcat from 'urlcat'
import { MethodAfterPersonaSign } from '../../../Wallet/type'

const useStyles = makeStyles()((theme) => ({
list: {
Expand Down Expand Up @@ -97,6 +100,7 @@ export interface ProfileListProps {}
export const ProfileList = memo(() => {
const { currentPersona } = PersonaContext.useContainer()

const navigate = useNavigate()
const [unbind, setUnbind] = useState<{
identifier: ProfileIdentifier
identity?: string
Expand Down Expand Up @@ -180,35 +184,21 @@ export const ProfileList = memo(() => {
unbind.platform,
)
if (!result) return
const signatureResult = await Services.Identity.signWithPersona({
method: 'eth',
message: result.signPayload,
identifier: currentPersona.identifier.toText(),
})

if (!signatureResult) return

// workaround: should remove this service method
await Services.Identity.detachProfileWithNextID(
unbind.identifier,
result.uuid,
publicHexKey,
NextIDAction.Delete,
unbind.platform,
unbind.identity,
result.createdAt,
{
signature: signatureResult.signature.signature,
},
navigate(
urlcat(PopupRoutes.PersonaSignRequest, {
requestID: Math.random().toString().slice(3),
message: result.signPayload,
identifier: currentPersona.identifier.toText(),
method: MethodAfterPersonaSign.DISCONNECT_NEXT_ID,
profileIdentifier: unbind.identifier.toText(),
platform: unbind.platform,
identity: unbind.identity,
createdAt: result.createdAt,
uuid: result.uuid,
}),
)

await delay(2000)
setUnbind(null)
refreshProfileList()
} catch {
console.log('Disconnect failed')
} finally {
MaskMessages.events.ownProofChanged.sendToAll(undefined)
}
}, [unbind, currentPersona?.identifier, refreshProfileList])

Expand Down
4 changes: 4 additions & 0 deletions packages/mask/src/extension/popups/pages/Wallet/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ export enum TransferAddressError {
RESOLVE_FAILED = 'RESOLVE_FAILED',
NETWORK_NOT_SUPPORT = 'NETWORK_NOT_SUPPORT',
}

export enum MethodAfterPersonaSign {
DISCONNECT_NEXT_ID = 'DISCONNECT_NEXT_ID',
}