|
1 | | -import React, { useState, useEffect, useCallback } from 'react' |
| 1 | +import React, { useState, useEffect, useCallback, useMemo } from 'react' |
2 | 2 | import { TFunction } from 'i18next' |
3 | 3 | import { useTranslation } from 'react-i18next' |
4 | 4 | import { showErrorMessage, signMessage, verifyMessage } from 'services/remote' |
5 | 5 | import { ControllerResponse } from 'services/remote/remoteApiWrapper' |
6 | | -import { ErrorCode, isSuccessResponse, shannonToCKBFormatter, useExitOnWalletChange, useGoBack } from 'utils' |
| 6 | +import { |
| 7 | + ErrorCode, |
| 8 | + isSuccessResponse, |
| 9 | + shannonToCKBFormatter, |
| 10 | + useExitOnWalletChange, |
| 11 | + useGoBack, |
| 12 | + validateAddress, |
| 13 | + isMainnet as isMainnetUtil, |
| 14 | +} from 'utils' |
| 15 | +import { isErrorWithI18n } from 'exceptions' |
7 | 16 | import { useState as useGlobalState } from 'states' |
8 | 17 | import Button from 'widgets/Button' |
9 | 18 | import Balance from 'widgets/Balance' |
@@ -130,8 +139,13 @@ const SignAndVerify = () => { |
130 | 139 | const [message, setMessage] = useState('') |
131 | 140 | const [signature, setSignature] = useState('') |
132 | 141 | const [address, setAddress] = useState('') |
133 | | - const { wallet } = useGlobalState() |
| 142 | + const { |
| 143 | + chain: { networkID }, |
| 144 | + settings: { networks }, |
| 145 | + wallet, |
| 146 | + } = useGlobalState() |
134 | 147 | const [isDropdownOpen, setIsDropdownOpen] = useState(false) |
| 148 | + const isMainnet = isMainnetUtil(networks, networkID) |
135 | 149 | useExitOnWalletChange() |
136 | 150 |
|
137 | 151 | const handlePasswordDialogOpen = useCallback(() => { |
@@ -226,12 +240,29 @@ const SignAndVerify = () => { |
226 | 240 |
|
227 | 241 | const onBack = useGoBack() |
228 | 242 |
|
| 243 | + const addressError = useMemo(() => { |
| 244 | + if (!address) { |
| 245 | + return undefined |
| 246 | + } |
| 247 | + try { |
| 248 | + validateAddress(address, isMainnet) |
| 249 | + } catch (err) { |
| 250 | + if (isErrorWithI18n(err)) { |
| 251 | + return t(err.message, err.i18n) |
| 252 | + } |
| 253 | + } |
| 254 | + if (wallet?.addresses && !wallet.addresses.find(item => item.address === address)) { |
| 255 | + return t('sign-and-verify.address-not-found') |
| 256 | + } |
| 257 | + return undefined |
| 258 | + }, [t, address, isMainnet, wallet.addresses]) |
| 259 | + |
229 | 260 | return ( |
230 | 261 | <div> |
231 | 262 | <Dialog |
232 | 263 | show={showDialog} |
233 | 264 | title={t('sign-and-verify.sign-or-verify-message')} |
234 | | - disabled={!message || !signature || !address} |
| 265 | + disabled={!message || !signature || !address || !!addressError} |
235 | 266 | onCancel={onBack} |
236 | 267 | confirmText={t('sign-and-verify.verify')} |
237 | 268 | onConfirm={handleVerifyMessage} |
@@ -270,6 +301,7 @@ const SignAndVerify = () => { |
270 | 301 | </div> |
271 | 302 | } |
272 | 303 | width="100%" |
| 304 | + error={addressError} |
273 | 305 | /> |
274 | 306 | </div> |
275 | 307 | {isDropdownOpen && wallet?.addresses ? ( |
@@ -311,7 +343,7 @@ const SignAndVerify = () => { |
311 | 343 |
|
312 | 344 | {wallet?.isWatchOnly || ( |
313 | 345 | <div className={styles.signWrap}> |
314 | | - <Button type="text" disabled={!message || !address} onClick={handlePasswordDialogOpen}> |
| 346 | + <Button type="text" disabled={!message || !address || !!addressError} onClick={handlePasswordDialogOpen}> |
315 | 347 | <Sign /> |
316 | 348 | {t('sign-and-verify.sign')} |
317 | 349 | </Button> |
|
0 commit comments