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
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const CreateMnemonic = memo(() => {
await PluginServices.Wallet.updateMaskAccount({
account: address_,
})
await PluginServices.Wallet.selectMaskAccount([address_])
await PluginServices.Wallet.resolveMaskAccount([address_])
}

return address_
Expand Down
2 changes: 2 additions & 0 deletions packages/mask/public/patches.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ globalThis.regeneratorRuntime = undefined
console.trace('[Trusted Types](default policy): Possible XSS happened. Please remove it.', string)
return string
},
createScriptURL: (string) => string,
createScript: (string) => string,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@nuanyang233 do not add createScript! This allows eval

})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
} from '@masknet/web3-shared-base'
import { CopyIconButton } from '../../../components/CopyIconButton'
import { useTitle } from '../../../hook/useTitle'
import { WalletRPC } from '../../../../../plugins/Wallet/messages'

const useStyles = makeStyles()(() => ({
container: {
Expand Down Expand Up @@ -266,7 +267,7 @@ const ContractInteraction = memo(() => {
const [{ loading }, handleConfirm] = useAsyncFn(async () => {
if (request) {
try {
await connection?.confirmRequest?.()
await WalletRPC.confirmRequest(request.payload)
navigate(-1)
} catch (error_) {
setTransferError(true)
Expand All @@ -277,7 +278,7 @@ const ContractInteraction = memo(() => {

const [{ loading: rejectLoading }, handleReject] = useAsyncFn(async () => {
if (!request) return
await connection?.rejectRequest?.()
await WalletRPC.rejectRequest(request.payload)
navigate(PopupRoutes.Wallet, { replace: true })
}, [request])

Expand Down Expand Up @@ -311,21 +312,6 @@ const ContractInteraction = memo(() => {
.plus(tokenValueUSD)
.toString()

console.log('DEBUG: ContractInteraction')
console.log({
amount,
gasFee,
gas,
maxPriorityFeePerGas: maxPriorityFeePerGas ?? defaultPrices?.maxPriorityFeePerGas,
maxFeePerGas: maxFeePerGas ?? defaultPrices?.maxFeePerGas,
defaultPrice: (gasPrice as string) ?? defaultPrices?.gasPrice,
request,
tokenPrice,
tokenAmount,
tokenDecimals,
nativeTokenPrice,
})

useUpdateEffect(() => {
if (!request && !requestLoading) {
navigate(PopupRoutes.Wallet, { replace: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const ImportWallet = memo(() => {
account: wallet,
})
}
await WalletRPC.selectMaskAccount([wallet])
await WalletRPC.resolveMaskAccount([wallet])
navigate(PopupRoutes.Wallet, { replace: true })
await Services.Helper.removePopupWindow()
break
Expand All @@ -186,11 +186,12 @@ const ImportWallet = memo(() => {
await WalletRPC.updateMaskAccount({
account: privateKeyWallet,
})
await WalletRPC.selectMaskAccount([privateKeyWallet])
await WalletRPC.resolveMaskAccount([privateKeyWallet])

await connection?.connect({
account: privateKeyWallet,
providerType: ProviderType.MaskWallet,
popupsWindow: false,
})

await Services.Helper.removePopupWindow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const SelectWallet = memo(() => {
if (isPopup) {
navigate(-1)
} else {
await WalletRPC.selectMaskAccount([])
await WalletRPC.resolveMaskAccount([])
await Services.Helper.removePopupWindow()
}
}, [isPopup])
Expand All @@ -142,7 +142,7 @@ const SelectWallet = memo(() => {
account: selected,
})
if (chainId) {
await WalletRPC.selectMaskAccount([selected])
await WalletRPC.resolveMaskAccount([selected])
}
return Services.Helper.removePopupWindow()
}, [chainId, selected, isPopup])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { PopupRoutes } from '@masknet/shared-base'
import { useTitle } from '../../../hook/useTitle'
import { EthereumMethodType } from '@masknet/web3-shared-evm'
import { NetworkPluginID } from '@masknet/web3-shared-base'
import { WalletRPC } from '../../../../../plugins/Wallet/messages'

const useStyles = makeStyles()(() => ({
container: {
Expand Down Expand Up @@ -117,9 +118,13 @@ const SignRequest = memo(() => {
}, [value])

const [{ loading }, handleConfirm] = useAsyncFn(async () => {
if (value && connection?.confirmRequest) {
const goBack = new URLSearchParams(routeLocation.search).get('goBack')

if (value) {
try {
await connection.confirmRequest()
await WalletRPC.confirmRequest(value.payload, {
disableClose: !!goBack,
})
navigate(-1)
} catch (error_) {
setTransferError(true)
Expand All @@ -128,8 +133,8 @@ const SignRequest = memo(() => {
}, [value, routeLocation.search, connection])

const [{ loading: rejectLoading }, handleReject] = useAsyncFn(async () => {
if (!value || !connection?.rejectRequest) return
await connection.rejectRequest()
if (!value) return
await WalletRPC.rejectRequest(value.payload)
navigate(PopupRoutes.Wallet, { replace: true })
}, [value, connection])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { memo } from 'react'
import { makeStyles } from '@masknet/theme'
import { PageHeader } from '../components/PageHeader'
import { MaskMessages, useI18N } from '../../../../../utils'
import { useLocation } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import { useAsync, useAsyncFn } from 'react-use'
import { ChainId, formatEthereumAddress, ProviderType } from '@masknet/web3-shared-evm'
import { formatEthereumAddress } from '@masknet/web3-shared-evm'
import Services from '../../../../service'
import { LoadingPlaceholder } from '../../../components/LoadingPlaceholder'
import { Typography } from '@mui/material'
Expand Down Expand Up @@ -78,6 +78,7 @@ const WalletRecovery = memo(() => {
const { t } = useI18N()
const { classes } = useStyles()
const location = useLocation()
const navigate = useNavigate()

const web3State = useWeb3State(NetworkPluginID.PLUGIN_EVM)

Expand Down Expand Up @@ -127,7 +128,8 @@ const WalletRecovery = memo(() => {
await Services.Backup.restoreUnconfirmedBackup({ id: backupId, action: 'confirm' })

// Set default wallet
if (json.wallets) await web3State.Provider?.connect(ChainId.Mainnet, ProviderType.MaskWallet)
if (json.wallets) await WalletRPC.setDefaultMaskAccount()

// Send event after successful recovery
MaskMessages.events.restoreSuccess.sendToAll(undefined)

Expand Down
19 changes: 4 additions & 15 deletions packages/mask/src/plugin-infra/host.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// All plugin manager need to call createPluginHost so let's register plugins implicitly.
import './register'

import type { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers'
import type { Plugin } from '@masknet/plugin-infra'
import { Emitter } from '@servie/events'
import { MaskMessages } from '../../shared/messages'
Expand All @@ -28,15 +26,7 @@ export function createSharedContext(pluginID: string, signal: AbortSignal): Plug
nativeType: nativeAPI?.type,
hasNativeAPI,

send: async (payload: JsonRpcPayload) => {
if (nativeAPI?.type === 'iOS') {
return nativeAPI.api.send(payload) as unknown as JsonRpcResponse
} else {
const response = await nativeAPI?.api.sendJsonString(JSON.stringify(payload))
if (!response) throw new Error('Failed to send request to native APP.')
return JSON.parse(response) as JsonRpcResponse
}
},
send: WalletRPC.sendPayload,

openPopupWindow: Services.Helper.openPopupWindow,
closePopupWindow: Services.Helper.removePopupWindow,
Expand Down Expand Up @@ -66,18 +56,17 @@ export function createSharedContext(pluginID: string, signal: AbortSignal): Plug

updateAccount: WalletRPC.updateMaskAccount,
resetAccount: WalletRPC.resetMaskAccount,
selectAccountPrepare: WalletRPC.selectMaskAccountPrepare,
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,

shiftUnconfirmedRequest: WalletRPC.shiftUnconfirmedRequest,
pushUnconfirmedRequest: WalletRPC.pushUnconfirmedRequest,
}
}

Expand Down
29 changes: 24 additions & 5 deletions packages/mask/src/plugins/Wallet/services/account.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { first } from 'lodash-unified'
import { EthereumAddress } from 'wallet.ts'
import { ChainId, chainResolver, networkResolver, NetworkType } from '@masknet/web3-shared-evm'
import {
Expand All @@ -6,6 +7,18 @@ import {
currentMaskWalletNetworkSettings,
} from '../settings'
import { Flags } from '../../../../shared'
import { WalletRPC } from '../messages'
import { defer, DeferTuple } from '@dimensiondev/kit'

export async function setDefaultMaskAccount() {
if (currentMaskWalletAccountSettings.value) return
const wallets = await WalletRPC.getWallets()
const address = first(wallets)?.address
if (address)
await updateMaskAccount({
account: address,
})
}

export async function updateMaskAccount(options: { account?: string; chainId?: ChainId; networkType?: NetworkType }) {
if (options.chainId && !options.networkType) options.networkType = chainResolver.chainNetworkType(options.chainId)
Expand All @@ -24,14 +37,20 @@ export async function resetMaskAccount() {
}

// #region select wallet with popups
let callbackMemorized: (accounts: string[]) => void | undefined
const deferred: DeferTuple<string[], Error> = defer<string[], Error>()

export async function selectMaskAccount(): Promise<string[]> {
return deferred[0]
}

export async function selectMaskAccountPrepare(callback: (accounts: string[]) => void) {
callbackMemorized = callback
export async function resolveMaskAccount(accounts: string[]) {
const [, resolve] = deferred
resolve?.(accounts)
}

export async function selectMaskAccount(accounts: string[]) {
callbackMemorized?.(accounts)
export async function rejectMaskAccount() {
const [, resolve] = deferred
resolve?.([])
}
// #endregion

Expand Down
1 change: 1 addition & 0 deletions packages/mask/src/plugins/Wallet/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './keystore'
export * from './wallet/index'
export * from './legacyWallet'
export * from './rpc'
export * from './send'
88 changes: 88 additions & 0 deletions packages/mask/src/plugins/Wallet/services/maskwallet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import type { MaskBaseAPI } from '@masknet/web3-providers'
import { api } from '@dimensiondev/mask-wallet-core/proto'
import { OnDemandWorker } from '@masknet/shared-base'

type Request = InstanceType<typeof api.MWRequest>
type Response = InstanceType<typeof api.MWResponse>

const Worker = new OnDemandWorker(new URL('../../../../../web-workers/wallet.ts', import.meta.url), {
name: 'MaskWallet',
})

enum ErrorCode {
KdfParamsInvalid = '-3001',
PasswordIncorrect = '-3002',
InvalidKeyIvLength = '-3003',
InvalidCiphertext = '-3004',
InvalidPrivateKey = '-3005',
InvalidPublicKey = '-3006',
InvalidMnemonic = '-3007',
InvalidSeed = '-3008',
InvalidDerivationPath = '-3009',
InvalidKeyStoreJSON = '-3010',
NotSupportedPublicKeyType = '-3011',
NotSupportedCurve = '-3012',
NotSupportedCipher = '-3013',
}

const ErrorMessage = {
[ErrorCode.KdfParamsInvalid]: 'Invalid kdf parameters.',
[ErrorCode.PasswordIncorrect]: 'Incorrect payment password.',
[ErrorCode.InvalidKeyIvLength]: 'Invalid key IV length.',
[ErrorCode.InvalidCiphertext]: 'Invalid cipher text.',
[ErrorCode.InvalidPrivateKey]: 'Invalid private key.',
[ErrorCode.InvalidPublicKey]: 'Invalid public key.',
[ErrorCode.InvalidMnemonic]: 'Invalid mnemonic words.',
[ErrorCode.InvalidSeed]: 'Invalid seed.',
[ErrorCode.InvalidDerivationPath]: 'Invalid derivation path.',
[ErrorCode.InvalidKeyStoreJSON]: 'Invalid keystore JSON.',
[ErrorCode.NotSupportedPublicKeyType]: 'Not supported public key type.',
[ErrorCode.NotSupportedCurve]: 'Not supported curve.',
[ErrorCode.NotSupportedCipher]: 'Not supported cipher.',
}

function send<I extends keyof Request, O extends keyof Response>(input: I, output: O) {
return (value: Request[I]) => {
return new Promise<Response[O]>((resolve, reject) => {
const req: MaskBaseAPI.Input = { id: Math.random(), data: { [input]: value } }
Worker.postMessage(req)
Worker.addEventListener('message', function f(message) {
if (message.data.id !== req.id) return

Worker.removeEventListener('message', f)
const data: MaskBaseAPI.Output = message.data
if (data.response.error)
return reject(
new Error(ErrorMessage[data.response.error.errorCode as ErrorCode] || 'Unknown Error'),
)
resolve(data.response[output])
})
})
}
}

export const Coin = api.Coin
export const StoredKeyType = api.StoredKeyType
export const StoredKeyImportType = api.StoredKeyImportType
export const StoredKeyExportType = api.StoredKeyExportType

export const loadStoredKey = send('param_load_stored_key', 'resp_load_stored_key')
export const createStoredKey = send('param_create_stored_key', 'resp_create_stored_key')
export const importPrivateKey = send('param_import_private_key', 'resp_import_private_key')
export const importMnemonic = send('param_import_mnemonic', 'resp_import_mnemonic')
export const importJSON = send('param_import_json', 'resp_import_json')
export const createAccountOfCoinAtPath = send(
'param_create_account_of_coin_at_path',
'resp_create_account_of_coin_at_path',
)
export const exportPrivateKey = send('param_export_private_key', 'resp_export_private_key')
export const exportPrivateKeyOfPath = send('param_export_private_key_of_path', 'resp_export_private_key')
export const exportMnemonic = send('param_export_mnemonic', 'resp_export_mnemonic')
export const exportKeyStoreJSONOfAddress = send('param_export_key_store_json_of_address', 'resp_export_key_store_json')
export const exportKeyStoreJSONOfPath = send('param_export_key_store_json_of_path', 'resp_export_key_store_json')
export const exportUpdateKeyStorePassword = send('param_update_key_store_password', 'resp_update_key_store_password')
export const signTransaction = send('param_sign_transaction', 'resp_sign_transaction')
export const getLibVersion = send('param_get_version', 'resp_get_version')
export const validate = send('param_validation', 'resp_validate')
export const getSupportImportTypes = send('param_get_stored_key_import_type', 'resp_get_stored_key_import_type')
export const getSupportExportTypes = send('param_get_stored_key_export_type', 'resp_get_stored_key_export_type')
Loading