From 54994c3c74131658d3f576a00d4501beea607d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E5=9B=BD=E5=AE=87?= <841185308@qq.com> Date: Mon, 1 Jul 2024 09:52:12 +0800 Subject: [PATCH] feat: Support reset lock window password (#3197) --- .../src/components/CellManagement/hooks.ts | 2 +- .../GeneralSetting/LockWindowDialog/hooks.ts | 4 +- .../GeneralSetting/LockWindowDialog/index.tsx | 2 +- .../src/containers/LockWindow/index.tsx | 70 +++++++-- .../LockWindow/lockWindow.module.scss | 16 ++ .../containers/LockWindow/verifyWallet.tsx | 121 ++++++++++++++ packages/neuron-ui/src/locales/en.json | 4 +- packages/neuron-ui/src/locales/es.json | 4 +- packages/neuron-ui/src/locales/fr.json | 4 +- packages/neuron-ui/src/locales/zh-tw.json | 4 +- packages/neuron-ui/src/locales/zh.json | 4 +- .../neuron-ui/src/types/Controller/index.d.ts | 2 +- .../neuron-ui/src/widgets/Dialog/index.tsx | 8 +- .../src/widgets/SplitPasswordInput/index.tsx | 147 +++++++++++------- packages/neuron-wallet/src/controllers/api.ts | 2 + .../src/controllers/cell-management.ts | 7 +- .../src/controllers/sign-message.ts | 10 +- .../src/services/sign-message.ts | 14 +- .../neuron-wallet/src/types/controller.d.ts | 2 +- .../tests/controllers/cell-management.test.ts | 10 +- .../tests/services/sign-message.test.ts | 21 ++- 21 files changed, 364 insertions(+), 94 deletions(-) create mode 100644 packages/neuron-ui/src/containers/LockWindow/verifyWallet.tsx diff --git a/packages/neuron-ui/src/components/CellManagement/hooks.ts b/packages/neuron-ui/src/components/CellManagement/hooks.ts index f0a746c5cb..1823cc98c0 100644 --- a/packages/neuron-ui/src/components/CellManagement/hooks.ts +++ b/packages/neuron-ui/src/components/CellManagement/hooks.ts @@ -398,7 +398,7 @@ export const usePassword = () => { } export const useHardWallet = ({ wallet, t }: { wallet: State.WalletIdentity; t: TFunction }) => { - const isWin32 = useMemo(() => { + const isWin32 = useMemo(() => { return getPlatform() === 'win32' }, []) const [error, setError] = useState() diff --git a/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/hooks.ts b/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/hooks.ts index a1213dc389..fe2e933eec 100644 --- a/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/hooks.ts +++ b/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/hooks.ts @@ -71,7 +71,7 @@ export const useRepeatPassword = ({ password: string t: TFunction encryptedPassword?: string - onCancel: () => void + onCancel: (success: boolean) => void }) => { const dispatch = useDispatch() const [errMsg, setErrMsg] = useState('') @@ -89,7 +89,7 @@ export const useRepeatPassword = ({ updateLockWindowInfo( encryptedPassword ? { password: updatedRepeatPassword } : { password: updatedRepeatPassword, locked: true } )(dispatch) - onCancel() + onCancel(true) } } else { setErrMsg('') diff --git a/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/index.tsx b/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/index.tsx index 629eda59f6..c9f0226413 100644 --- a/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/index.tsx +++ b/packages/neuron-ui/src/components/GeneralSetting/LockWindowDialog/index.tsx @@ -13,7 +13,7 @@ const LockWindowDialog = ({ encryptedPassword, }: { show: boolean - onCancel: () => void + onCancel: (success?: boolean) => void encryptedPassword?: string }) => { const [t] = useTranslation() diff --git a/packages/neuron-ui/src/containers/LockWindow/index.tsx b/packages/neuron-ui/src/containers/LockWindow/index.tsx index 3afb787ed2..cc39bf31db 100644 --- a/packages/neuron-ui/src/containers/LockWindow/index.tsx +++ b/packages/neuron-ui/src/containers/LockWindow/index.tsx @@ -1,5 +1,5 @@ /* eslint-disable jsx-a11y/media-has-caption */ -import React, { useCallback, useEffect, useState } from 'react' +import React, { useCallback, useEffect, useRef, useState } from 'react' import { AppActions, getLockWindowInfo, useDispatch, useState as useGlobalState } from 'states' import Spinner from 'widgets/Spinner' import Locked from 'widgets/Icons/Locked.png' @@ -8,10 +8,13 @@ import UnLockMp4 from 'widgets/Icons/unlock.mp4' import SplitPasswordInput from 'widgets/SplitPasswordInput' import { useTranslation } from 'react-i18next' import { clsx, isSuccessResponse } from 'utils' -import { isDark, unlockWindow } from 'services/remote' +import { isDark, signMessage, unlockWindow } from 'services/remote' import { retryUnlockWindow } from 'services/localCache' import { MILLISECS_PER_HOUR, MILLISECS_PER_MIN, MILLISECS_PER_SEC } from 'utils/getSyncLeftTime' +import { ControllerResponse } from 'services/remote/remoteApiWrapper' +import LockWindowDialog from 'components/GeneralSetting/LockWindowDialog' import styles from './lockWindow.module.scss' +import VerifyWallet from './verifyWallet' const passwordLen = 4 const wrongEnterTimes = 3 @@ -24,12 +27,6 @@ const formatterLockMillisecs = (lockMillisecs: number) => { const getWaitMillisecs = (retryTimes: number) => { if (retryTimes % wrongEnterTimes === 0) { - if (retryTimes >= 3 * wrongEnterTimes) { - return 24 * MILLISECS_PER_HOUR - } - if (retryTimes > wrongEnterTimes) { - return 30 * MILLISECS_PER_MIN - } return 5 * MILLISECS_PER_MIN } return undefined @@ -41,7 +38,7 @@ const LockWindow = ({ children }: { children: React.ReactNode }) => { useEffect(() => { getLockWindowInfo(dispatch) }, []) - const { app } = useGlobalState() + const { app, wallet } = useGlobalState() const [password, setPassword] = useState(new Array(passwordLen).fill('')) const [errMsg, setErrMsg] = useState('') const [retryUnlockInfo, setRetryUnlockInfo] = useState(retryUnlockWindow.get()) @@ -130,6 +127,25 @@ const LockWindow = ({ children }: { children: React.ReactNode }) => { } return () => clearInterval(interval) }, [retryUnlockInfo]) + const splitPasswordInputRef = useRef<{ focus: () => void } | null>(null) + const [isVerifyWalletDialogShow, setIsVerifyWalletDialogShow] = useState(false) + const [isResetPasswordDialogShow, setIsResetPasswordDialogShow] = useState(false) + const onVerifyWallet = useCallback( + async (walletPassword?: string) => { + const res: ControllerResponse = await signMessage({ + walletID: wallet?.id ?? '', + message: 'verify wallet for reset lock window password', + password: walletPassword ?? '', + }) + if (isSuccessResponse(res)) { + setIsVerifyWalletDialogShow(false) + setIsResetPasswordDialogShow(true) + } else { + throw new Error(typeof res.message === 'string' ? res.message : res.message.content) + } + }, + [setIsResetPasswordDialogShow, setIsVerifyWalletDialogShow, wallet] + ) if (!app.lockWindowInfo) { return (
@@ -156,11 +172,47 @@ const LockWindow = ({ children }: { children: React.ReactNode }) => { disabled={retryUnlockInfo.retryTimes % wrongEnterTimes === 0 && !!retryUnlockInfo.lastRetryTime} values={password} onChange={onUpdatePassword} + ref={splitPasswordInputRef} />
{errMsg || t('lock-window.enter-lock-password')} + {wallet.isWatchOnly ? null : ( + + )}
+ { + setIsVerifyWalletDialogShow(false) + setTimeout(() => { + // wait for dialog close + splitPasswordInputRef.current?.focus() + }, 10) + }} + onConfirm={onVerifyWallet} + /> + { + setIsResetPasswordDialogShow(false) + if (success) { + setPassword(new Array(passwordLen).fill('')) + } + setTimeout(() => { + // wait for dialog close + splitPasswordInputRef.current?.focus() + }, 10) + }} + /> ) } diff --git a/packages/neuron-ui/src/containers/LockWindow/lockWindow.module.scss b/packages/neuron-ui/src/containers/LockWindow/lockWindow.module.scss index a35391d16b..f6eb32bddb 100644 --- a/packages/neuron-ui/src/containers/LockWindow/lockWindow.module.scss +++ b/packages/neuron-ui/src/containers/LockWindow/lockWindow.module.scss @@ -20,6 +20,13 @@ &[data-has-err='true'] { color: var(--error-color); } + + & > button { + border: none; + color: var(--primary-color); + background-color: transparent; + cursor: pointer; + } } .passwordContainer { @@ -53,3 +60,12 @@ height: 88px; } } + +.verifyWallet { + min-width: 600px; + + .hardwalletErr { + justify-content: center; + margin-top: 12px; + } +} diff --git a/packages/neuron-ui/src/containers/LockWindow/verifyWallet.tsx b/packages/neuron-ui/src/containers/LockWindow/verifyWallet.tsx new file mode 100644 index 0000000000..f5822e8535 --- /dev/null +++ b/packages/neuron-ui/src/containers/LockWindow/verifyWallet.tsx @@ -0,0 +1,121 @@ +import React, { useCallback, useEffect, useState } from 'react' +import Dialog from 'widgets/Dialog' +import Hardware from 'widgets/Icons/Hardware.png' +import Button from 'widgets/Button' +import { useHardWallet, usePassword } from 'components/CellManagement/hooks' +import Alert from 'widgets/Alert' +import TextField from 'widgets/TextField' +import { useTranslation } from 'react-i18next' +import styles from './lockWindow.module.scss' + +const VerifyWallet = ({ + wallet, + show, + onCancel, + onConfirm, +}: { + wallet: State.Wallet + show: boolean + onCancel: () => void + onConfirm: (password?: string) => Promise +}) => { + const [t] = useTranslation() + const [loading, setLoading] = useState(false) + const { + isReconnecting, + isNotAvailable, + reconnect, + verifyDeviceStatus, + errorMessage: hardwalletError, + setError: setHardwalletError, + } = useHardWallet({ + wallet, + t, + }) + const { password, error, onPasswordChange, setError, resetPassword } = usePassword() + useEffect(() => { + if (show) { + resetPassword() + } + }, [show, resetPassword]) + useEffect(() => { + if (show && wallet.device) { + verifyDeviceStatus() + } + }, [show, wallet.device, verifyDeviceStatus]) + const onConfirmWrapper = useCallback(() => { + setLoading(true) + onConfirm(wallet.device ? undefined : password) + .catch(err => { + if (wallet.device) { + setHardwalletError(err.message) + } else { + setError(err.message) + } + }) + .finally(() => { + setLoading(false) + }) + }, [wallet.device, onConfirm, setLoading, setHardwalletError, setError, password]) + if (wallet.device) { + return ( + +
+ hard-wallet +
+
+ +
+ {hardwalletError ? ( + + {hardwalletError} + + ) : null} +
+ ) + } + return ( + + + + ) +} + +VerifyWallet.displayName = 'VerifyWallet' + +export default VerifyWallet diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index e37c643389..e62b080695 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -1301,8 +1301,10 @@ "lock-window": { "neuron-is-locked": "Neuron's window has been locked", "enter-lock-password": "Enter lock password", + "forget-password": "Forget password?", "lock-password-error": "Lock windows password error", - "failed-times": "Failed more than {{frequency}} times, please retry after {{time}}" + "failed-times": "Failed more than {{frequency}} times, please retry after {{time}}", + "verify-wallet": "Verify" } } } diff --git a/packages/neuron-ui/src/locales/es.json b/packages/neuron-ui/src/locales/es.json index 292de516e2..4d4f9f3e2c 100644 --- a/packages/neuron-ui/src/locales/es.json +++ b/packages/neuron-ui/src/locales/es.json @@ -1281,8 +1281,10 @@ "lock-window": { "neuron-is-locked": "La ventana de Neuron está bloqueada", "enter-lock-password": "Ingresar contraseña de bloqueo de pantalla", + "forget-password": "Olvidé mi contraseña?", "lock-password-error": "Contraseña de bloqueo de pantalla incorrecta", - "failed-times": "Fallo más de {{frequency}} veces, por favor inténtalo de nuevo después de {{time}}" + "failed-times": "Fallo más de {{frequency}} veces, por favor inténtalo de nuevo después de {{time}}", + "verify-wallet": "Verificar" } } } diff --git a/packages/neuron-ui/src/locales/fr.json b/packages/neuron-ui/src/locales/fr.json index 680b411a03..5bf2ce6d0d 100644 --- a/packages/neuron-ui/src/locales/fr.json +++ b/packages/neuron-ui/src/locales/fr.json @@ -1291,8 +1291,10 @@ "lock-window": { "neuron-is-locked": "a fenêtre de Neuron est verrouillée", "enter-lock-password": "Entrer le mot de passe de verrouillage d'écran", + "forget-password": "Mot de passe oublié?", "lock-password-error": "Mot de passe de verrouillage d'écran incorrect", - "failed-times": "Échec plus de {{frequency}} fois, veuillez réessayer après {{time}}" + "failed-times": "Échec plus de {{frequency}} fois, veuillez réessayer après {{time}}", + "verify-wallet": "Vérifier" } } } diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index 899bfc41e1..b354a95306 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -1290,8 +1290,10 @@ "lock-window": { "neuron-is-locked": "Neuron 窗口已鎖定", "enter-lock-password": "輸入鎖屏密碼", + "forget-password": "忘記密碼?", "lock-password-error": "鎖屏密碼錯誤", - "failed-times": "失敗超過 {{frequency}} 次, 請在 {{time}} 後重試" + "failed-times": "失敗超過 {{frequency}} 次, 請在 {{time}} 後重試", + "verify-wallet": "驗證" } } } diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 28d1944f35..284b245276 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -1293,8 +1293,10 @@ "lock-window": { "neuron-is-locked": "Neuron 窗口已锁定", "enter-lock-password": "输入锁屏密码", + "forget-password": "忘记密码?", "lock-password-error": "锁屏密码错误", - "failed-times": "失败超过 {{frequency}} 次, 请在 {{time}} 后重试" + "failed-times": "失败超过 {{frequency}} 次, 请在 {{time}} 后重试", + "verify-wallet": "验证" } } } diff --git a/packages/neuron-ui/src/types/Controller/index.d.ts b/packages/neuron-ui/src/types/Controller/index.d.ts index 3f3d1a1940..83d7cab827 100644 --- a/packages/neuron-ui/src/types/Controller/index.d.ts +++ b/packages/neuron-ui/src/types/Controller/index.d.ts @@ -167,7 +167,7 @@ declare namespace Controller { interface SignMessageParams { walletID: string - address: string + address?: string password: string message: string } diff --git a/packages/neuron-ui/src/widgets/Dialog/index.tsx b/packages/neuron-ui/src/widgets/Dialog/index.tsx index 607bad0d91..7a0056c25e 100644 --- a/packages/neuron-ui/src/widgets/Dialog/index.tsx +++ b/packages/neuron-ui/src/widgets/Dialog/index.tsx @@ -77,7 +77,13 @@ const Dialog = ({ (e.key === 'Escape' && enableCloseWithEsc ? onCancel : undefined)} + onKeyDown={e => { + if (e.key === 'Escape' && enableCloseWithEsc) { + onCancel?.() + } else if (e.key === 'Enter' && showFooter && showConfirm) { + handleConfirm(e) + } + }} role="none" > {showHeader ? ( diff --git a/packages/neuron-ui/src/widgets/SplitPasswordInput/index.tsx b/packages/neuron-ui/src/widgets/SplitPasswordInput/index.tsx index 71a1e56c76..64637d2a1f 100644 --- a/packages/neuron-ui/src/widgets/SplitPasswordInput/index.tsx +++ b/packages/neuron-ui/src/widgets/SplitPasswordInput/index.tsx @@ -1,65 +1,96 @@ -import React, { useCallback, useEffect, useRef } from 'react' +import React, { + type ForwardedRef, + forwardRef, + useCallback, + useEffect, + useImperativeHandle, + useRef, + useState, +} from 'react' import styles from './splitPasswordInput.module.scss' -const SplitPasswordInput = ({ - values, - inputCount, - onChange, - disabled, -}: { - values: (string | undefined)[] - inputCount?: number - onChange: (value: string, idx: number) => void - disabled?: boolean -}) => { - const ref = useRef(null) - const onChangeInput = useCallback>( - e => { - const { dataset, value } = e.currentTarget - if (value.length > 1 || !dataset.idx) return - onChange(value, +dataset.idx) - if (ref.current && value.length > 0) { - const nextInput = ref.current.querySelector(`input:nth-child(${+dataset.idx + 2})`) as HTMLInputElement - nextInput?.focus() - } +const SplitPasswordInput = forwardRef( + ( + { + values, + inputCount, + onChange, + disabled, + }: { + values: (string | undefined)[] + inputCount?: number + onChange: (value: string, idx: number) => void + disabled?: boolean }, - [ref, values] - ) - const onKeyDown = useCallback>( - e => { - const { dataset, value } = e.currentTarget - if (e.key === 'Backspace' && dataset.idx && +dataset.idx > 0 && ref.current && value.length === 0) { - const lastInput = ref.current.querySelector(`input:nth-child(${+dataset.idx})`) as HTMLInputElement - lastInput?.focus() - onChange('', +dataset.idx - 1) + handlerRef: ForwardedRef<{ focus: () => void }> + ) => { + const ref = useRef(null) + const [focusIdx, setFocusIdx] = useState() + useImperativeHandle( + handlerRef, + () => { + return { + focus() { + if (ref.current && focusIdx !== undefined) { + const currentInput = ref.current.querySelector(`input:nth-child(${focusIdx})`) as HTMLInputElement + currentInput?.focus() + } + }, + } + }, + [focusIdx, ref] + ) + const onChangeInput = useCallback>( + e => { + const { dataset, value } = e.currentTarget + if (value.length > 1 || !dataset.idx) return + onChange(value, +dataset.idx) + if (ref.current && value.length > 0) { + const nextInput = ref.current.querySelector(`input:nth-child(${+dataset.idx + 2})`) as HTMLInputElement + nextInput?.focus() + setFocusIdx(+dataset.idx + 2) + } + }, + [ref, values] + ) + const onKeyDown = useCallback>( + e => { + const { dataset, value } = e.currentTarget + if (e.key === 'Backspace' && dataset.idx && +dataset.idx > 0 && ref.current && value.length === 0) { + const lastInput = ref.current.querySelector(`input:nth-child(${+dataset.idx})`) as HTMLInputElement + lastInput?.focus() + onChange('', +dataset.idx - 1) + setFocusIdx(+dataset.idx) + } + }, + [ref, values, setFocusIdx] + ) + useEffect(() => { + if (ref.current && values.join('').length === 0) { + const firstInput = ref.current.querySelector(`input:nth-child(1)`) as HTMLInputElement + firstInput?.focus() + setFocusIdx(1) } - }, - [ref, values] - ) - useEffect(() => { - if (ref.current && values.join('').length === 0) { - const firstInput = ref.current.querySelector(`input:nth-child(1)`) as HTMLInputElement - firstInput?.focus() - } - }, [values]) - return ( -
- {Array.from({ length: inputCount ?? values.length }).map((_, idx) => ( - - ))} -
- ) -} + }, [values, setFocusIdx]) + return ( +
+ {Array.from({ length: inputCount ?? values.length }).map((_, idx) => ( + + ))} +
+ ) + } +) SplitPasswordInput.displayName = 'SplitPasswordInput' export default SplitPasswordInput diff --git a/packages/neuron-wallet/src/controllers/api.ts b/packages/neuron-wallet/src/controllers/api.ts index 911baa4d96..7f5b8b6aed 100644 --- a/packages/neuron-wallet/src/controllers/api.ts +++ b/packages/neuron-wallet/src/controllers/api.ts @@ -65,6 +65,7 @@ import CellManagement from './cell-management' import { UpdateCellLocalInfo } from '../database/chain/entities/cell-local-info' import { CKBLightRunner } from '../services/light-runner' import { OutPoint } from '@ckb-lumos/base' +import { updateApplicationMenu } from './app/menu' export type Command = 'export-xpubkey' | 'import-xpubkey' | 'delete-wallet' | 'backup-wallet' // Handle channel messages from renderer process and user actions. @@ -317,6 +318,7 @@ export default class ApiController { handle('update-lock-window-info', async (_, params: { locked?: boolean; password?: string }) => { SettingsService.getInstance().updateLockWindowInfo(params) + updateApplicationMenu(BrowserWindow.getFocusedWindow()) return { status: ResponseCode.Success, result: SettingsService.getInstance().lockWindowInfo, diff --git a/packages/neuron-wallet/src/controllers/cell-management.ts b/packages/neuron-wallet/src/controllers/cell-management.ts index 4e0ee8ce20..9bf158a65f 100644 --- a/packages/neuron-wallet/src/controllers/cell-management.ts +++ b/packages/neuron-wallet/src/controllers/cell-management.ts @@ -69,7 +69,12 @@ export default class CellManagement { const addresses = new Set((await AddressService.getAddressesByWalletId(currentWallet.id)).map(v => v.address)) const isMainnet = NetworksService.getInstance().isMainnet() if (!lockScripts.every(v => addresses.has(scriptToAddress(v, isMainnet)))) throw new AddressNotFound() - await SignMessage.sign(currentWallet.id, scriptToAddress(lockScripts[0], isMainnet), password, 'verify cell owner') + await SignMessage.sign({ + walletID: currentWallet.id, + password, + message: 'verify cell owner', + address: scriptToAddress(lockScripts[0], isMainnet), + }) return CellLocalInfoService.updateLiveCellLockStatus(outPoints, locked) } diff --git a/packages/neuron-wallet/src/controllers/sign-message.ts b/packages/neuron-wallet/src/controllers/sign-message.ts index a81916b7f6..cd2d9d0233 100644 --- a/packages/neuron-wallet/src/controllers/sign-message.ts +++ b/packages/neuron-wallet/src/controllers/sign-message.ts @@ -4,12 +4,10 @@ import { ResponseCode } from '../utils/const' export default class SignMessageController { public async sign(params: Controller.Params.SignParams): Promise> { - const signature: string = await SignMessage.sign( - params.walletID, - params.address.trim(), - params.password, - params.message - ) + const signature: string = await SignMessage.sign({ + ...params, + address: params.address?.trim(), + }) if (!signature) { throw new ServiceHasNoResponse('Sign') } diff --git a/packages/neuron-wallet/src/services/sign-message.ts b/packages/neuron-wallet/src/services/sign-message.ts index aeaf32dca7..31882eba15 100644 --- a/packages/neuron-wallet/src/services/sign-message.ts +++ b/packages/neuron-wallet/src/services/sign-message.ts @@ -13,10 +13,20 @@ export default class SignMessage { private static ec = new EC('secp256k1') private static magicString = 'Nervos Message:' - public static async sign(walletID: string, address: string, password: string, message: string): Promise { + public static async sign({ + walletID, + password, + message, + address, + }: { + walletID: string + password: string + message: string + address?: string + }): Promise { const wallet = WalletService.getInstance().get(walletID) const addresses = await AddressService.getAddressesByWalletId(walletID) - let addr = addresses.find(addr => addr.address === address) + let addr = address ? addresses.find(addr => addr.address === address) : addresses[0] if (!addr) { throw new AddressNotFound() } diff --git a/packages/neuron-wallet/src/types/controller.d.ts b/packages/neuron-wallet/src/types/controller.d.ts index a59ea9fa0a..09ec01d15d 100644 --- a/packages/neuron-wallet/src/types/controller.d.ts +++ b/packages/neuron-wallet/src/types/controller.d.ts @@ -65,7 +65,7 @@ declare namespace Controller { interface SignParams { walletID: string - address: string + address?: string password: string message: string } diff --git a/packages/neuron-wallet/tests/controllers/cell-management.test.ts b/packages/neuron-wallet/tests/controllers/cell-management.test.ts index eb5a357e29..c41d19326f 100644 --- a/packages/neuron-wallet/tests/controllers/cell-management.test.ts +++ b/packages/neuron-wallet/tests/controllers/cell-management.test.ts @@ -57,8 +57,7 @@ jest.mock('../../src/services/addresses', () => ({ })) jest.mock('../../src/services/sign-message', () => ({ - sign: (walletID: string, address: string, password: string, message: string) => - signMock(walletID, address, password, message), + sign: (params: { walletID: string; address?: string; password: string; message: string }) => signMock(params), })) jest.mock('../../src/services/cell-local-info', () => ({ @@ -155,7 +154,12 @@ describe('CellManage', () => { getAddressesByWalletIdMock.mockResolvedValueOnce([{ address }]) const outPoints = [new OutPoint(`0x${'00'.repeat(32)}`, '0')] await CellManagement.updateLiveCellsLockStatus(outPoints, true, [lockScript], 'password') - expect(signMock).toBeCalledWith('walletId1', address, 'password', 'verify cell owner') + expect(signMock).toBeCalledWith({ + walletID: 'walletId1', + password: 'password', + message: 'verify cell owner', + address, + }) expect(updateLiveCellLockStatusMock).toBeCalledWith(outPoints, true) }) }) diff --git a/packages/neuron-wallet/tests/services/sign-message.test.ts b/packages/neuron-wallet/tests/services/sign-message.test.ts index 50bc48c7e9..d093abab06 100644 --- a/packages/neuron-wallet/tests/services/sign-message.test.ts +++ b/packages/neuron-wallet/tests/services/sign-message.test.ts @@ -78,14 +78,24 @@ describe(`SignMessage`, () => { it('not match wallet address', async () => { getAddressesByWalletIdMock.mockReturnValueOnce([]) await expect( - SignMessage.sign('walletId', signInfo.address, extendedKeyInfo.password, signInfo.message) + SignMessage.sign({ + walletID: 'walletId', + password: extendedKeyInfo.password, + message: signInfo.message, + address: signInfo.address, + }) ).rejects.toThrow(new AddressNotFound()) }) it('with generate', async () => { getAddressesByWalletIdMock.mockReturnValueOnce([{ address: signInfo.address }]) getPrivateKeyMock.mockReturnValueOnce(signInfo.privateKey) - const res = await SignMessage.sign('walletId', signInfo.address, extendedKeyInfo.password, signInfo.message) + const res = await SignMessage.sign({ + walletID: 'walletId', + password: extendedKeyInfo.password, + message: signInfo.message, + address: signInfo.address, + }) expect(res).toEqual(signInfo.signature) }) @@ -94,7 +104,12 @@ describe(`SignMessage`, () => { walletMock.mockReturnValueOnce({ isHardware: () => true }) const signMessage = jest.fn() hardWalletMock.mockReturnValueOnce({ signMessage }) - await SignMessage.sign('walletId', signInfo.address, extendedKeyInfo.password, signInfo.message) + await SignMessage.sign({ + walletID: 'walletId', + password: extendedKeyInfo.password, + message: signInfo.message, + address: signInfo.address, + }) expect(signMessage).toHaveBeenCalled() }) })