|
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