From 2f06b36caf3ff56aeabc158bec7cb4266418edff Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Tue, 21 Jan 2025 13:24:55 +0700 Subject: [PATCH 1/4] [Issue-3974] Fix: cannot import token & NFT on Rootstock --- package.json | 2 +- packages/extension-base/package.json | 2 +- packages/extension-koni-ui/package.json | 2 +- .../src/Popup/Home/Nfts/NftImport.tsx | 13 +++++++++++-- .../Popup/Settings/Tokens/FungibleTokenImport.tsx | 13 +++++++++++-- .../src/utils/account/reformatContractAddress.ts | 15 +++++++++++++++ packages/extension-web-ui/package.json | 2 +- yarn.lock | 14 +++++++------- 8 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts diff --git a/package.json b/package.json index fc9ee8ba77e..47aa77ed452 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "@polkadot/types-support": "^15.0.1", "@polkadot/util": "^13.2.3", "@polkadot/util-crypto": "^13.2.3", - "@subwallet/chain-list": "0.2.97", + "@subwallet/chain-list": "0.2.98-beta.6", "@subwallet/keyring": "^0.1.8-beta.0", "@subwallet/react-ui": "5.1.2-b79", "@subwallet/ui-keyring": "0.1.8-beta.0", diff --git a/packages/extension-base/package.json b/packages/extension-base/package.json index 2d65f302c51..b3998b631ff 100644 --- a/packages/extension-base/package.json +++ b/packages/extension-base/package.json @@ -55,7 +55,7 @@ "@reduxjs/toolkit": "^1.9.1", "@sora-substrate/type-definitions": "^1.17.7", "@substrate/connect": "^0.8.9", - "@subwallet/chain-list": "0.2.97", + "@subwallet/chain-list": "0.2.98-beta.6", "@subwallet/extension-base": "^1.3.12-1", "@subwallet/extension-chains": "^1.3.12-1", "@subwallet/extension-dapp": "^1.3.12-1", diff --git a/packages/extension-koni-ui/package.json b/packages/extension-koni-ui/package.json index 2530fe88cf1..ca105c932bd 100644 --- a/packages/extension-koni-ui/package.json +++ b/packages/extension-koni-ui/package.json @@ -34,7 +34,7 @@ "@polkadot/util-crypto": "^12.6.2", "@ramonak/react-progress-bar": "^5.0.3", "@reduxjs/toolkit": "^1.9.1", - "@subwallet/chain-list": "0.2.97", + "@subwallet/chain-list": "0.2.98-beta.6", "@subwallet/extension-base": "^1.3.12-1", "@subwallet/extension-chains": "^1.3.12-1", "@subwallet/extension-dapp": "^1.3.12-1", diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx index e5064a4296a..0c0e7f05754 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx @@ -18,6 +18,7 @@ import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; import { isAddress, isEthereumAddress } from '@polkadot/util-crypto'; +import {reformatContractAddress} from "@subwallet/extension-koni-ui/utils/account/reformatContractAddress"; type Props = ThemeProps; @@ -92,7 +93,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const empty = Object.entries(all).some(([key, value]) => key !== 'symbol' ? !value : false); - const { chain, type } = changes; + const { chain, type, contractAddress } = changes; if (chain) { const nftTypes = getNftTypeSupported(chainInfoMap[chain]); @@ -110,6 +111,10 @@ function Component ({ className = '' }: Props): React.ReactElement { form.resetFields(['contractAddress', 'collectionName']); } + if (contractAddress) { + form.setFieldValue('contractAddress', reformatContractAddress(selectedChain, contractAddress)); + } + if (allError.contractAddress.length > 0) { form.resetFields(['collectionName']); } @@ -182,6 +187,10 @@ function Component ({ className = '' }: Props): React.ReactElement { }); }, [t]); + const contractAddressTransform = useCallback((contractAddress: string) => { + return reformatContractAddress(selectedChain, contractAddress); + }, [selectedChain]) + const contractAddressValidator = useCallback((rule: RuleObject, contractAddress: string): Promise => { return new Promise((resolve, reject) => { if (!isAddress(contractAddress)) { @@ -291,7 +300,7 @@ function Component ({ className = '' }: Props): React.ReactElement { { const contractRules = useMemo((): FormRule[] => { return [ - ({ getFieldValue }) => ({ + ({ getFieldValue }) => ({ + transform: (contractAddress) => { + return reformatContractAddress(selectedChain, contractAddress); + }, validator: (_, contractAddress: string) => { return new Promise((resolve, reject) => { const selectedTokenType = getFieldValue('type') as _AssetType; + const isValidEvmContract = [_AssetType.ERC20].includes(selectedTokenType) && isEthereumAddress(contractAddress); const isValidWasmContract = [_AssetType.PSP22].includes(selectedTokenType) && isValidSubstrateAddress(contractAddress); const isValidGearContract = [_AssetType.VFT].includes(selectedTokenType) && isValidSubstrateAddress(contractAddress); @@ -210,7 +215,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const all = convertFieldToObject(allFields); const allError = convertFieldToError(allFields); - const { chain, type } = changes; + const { chain, type, contractAddress } = changes; const baseResetFields = ['tokenName', 'symbol', 'decimals', 'priceId']; @@ -232,6 +237,10 @@ function Component ({ className = '' }: Props): React.ReactElement { form.resetFields(['assetId', ...baseResetFields]); } + if (contractAddress) { + form.setFieldValue('contractAddress', reformatContractAddress(selectedChain, contractAddress)); + } + if (allError.contractAddress.length > 0 || allError.assetId.length > 0) { form.resetFields([...baseResetFields]); } diff --git a/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts b/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts new file mode 100644 index 00000000000..edaf1212c20 --- /dev/null +++ b/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts @@ -0,0 +1,15 @@ +// Copyright 2019-2022 @polkadot/extension-ui authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import {isEthereumAddress} from "@polkadot/util-crypto"; +import {reformatAddress} from "@subwallet/extension-koni-ui/utils"; + +const SPECIAL_CHAIN = ['rootstock']; + +export function reformatContractAddress (chainSlug: string, contractAddress: string) { + if (SPECIAL_CHAIN.includes(chainSlug) && isEthereumAddress(contractAddress.toLowerCase())) { + return reformatAddress(contractAddress.toLowerCase()); + } + + return contractAddress; +} diff --git a/packages/extension-web-ui/package.json b/packages/extension-web-ui/package.json index 9d2c8114ca0..40b42738c40 100644 --- a/packages/extension-web-ui/package.json +++ b/packages/extension-web-ui/package.json @@ -35,7 +35,7 @@ "@polkadot/util-crypto": "^12.6.2", "@ramonak/react-progress-bar": "^5.0.3", "@reduxjs/toolkit": "^1.9.1", - "@subwallet/chain-list": "0.2.97", + "@subwallet/chain-list": "0.2.98-beta.6", "@subwallet/extension-base": "^1.3.12-1", "@subwallet/extension-chains": "^1.3.12-1", "@subwallet/extension-dapp": "^1.3.12-1", diff --git a/yarn.lock b/yarn.lock index 39db93445c7..a5ca35b5329 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6439,15 +6439,15 @@ __metadata: languageName: node linkType: hard -"@subwallet/chain-list@npm:0.2.97": - version: 0.2.97 - resolution: "@subwallet/chain-list@npm:0.2.97" +"@subwallet/chain-list@npm:0.2.98-beta.6": + version: 0.2.98-beta.6 + resolution: "@subwallet/chain-list@npm:0.2.98-beta.6" dependencies: "@polkadot/dev": 0.67.167 "@polkadot/util": ^12.5.1 eventemitter3: ^5.0.1 ts-md5: ^1.3.1 - checksum: 3271231e2c5b435dd2f4c502da5af8b547a5ac8aafe7089d09c9966fd74b233eb4077d04e0c960857d5b5e2fbd29f178f08aec473e6ec23d19bd07b6642af432 + checksum: 6379d32e6ebbb0ee147d591effbd21474b9a6c44de242fcde025520a5b71ae26ec9ddb2a7949b701fedd5fbe863e9b0309b12c6ac185eec80a541c54c45f553c languageName: node linkType: hard @@ -6490,7 +6490,7 @@ __metadata: "@reduxjs/toolkit": ^1.9.1 "@sora-substrate/type-definitions": ^1.17.7 "@substrate/connect": ^0.8.9 - "@subwallet/chain-list": 0.2.97 + "@subwallet/chain-list": 0.2.98-beta.6 "@subwallet/extension-base": ^1.3.12-1 "@subwallet/extension-chains": ^1.3.12-1 "@subwallet/extension-dapp": ^1.3.12-1 @@ -6629,7 +6629,7 @@ __metadata: "@polkadot/util-crypto": ^12.6.2 "@ramonak/react-progress-bar": ^5.0.3 "@reduxjs/toolkit": ^1.9.1 - "@subwallet/chain-list": 0.2.97 + "@subwallet/chain-list": 0.2.98-beta.6 "@subwallet/extension-base": ^1.3.12-1 "@subwallet/extension-chains": ^1.3.12-1 "@subwallet/extension-dapp": ^1.3.12-1 @@ -6769,7 +6769,7 @@ __metadata: "@polkadot/util-crypto": ^12.6.2 "@ramonak/react-progress-bar": ^5.0.3 "@reduxjs/toolkit": ^1.9.1 - "@subwallet/chain-list": 0.2.97 + "@subwallet/chain-list": 0.2.98-beta.6 "@subwallet/extension-base": ^1.3.12-1 "@subwallet/extension-chains": ^1.3.12-1 "@subwallet/extension-dapp": ^1.3.12-1 From 94a8bc4ef9bde800d13c4ba1314a5d0ebf2f0b34 Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Tue, 21 Jan 2025 14:42:54 +0700 Subject: [PATCH 2/4] [Issue-3974] Fix lint --- .../src/Popup/Home/Nfts/NftImport.tsx | 8 ++++---- .../Popup/Settings/Tokens/FungibleTokenImport.tsx | 12 ++++++------ .../src/utils/account/reformatContractAddress.ts | 5 +++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx index 0c0e7f05754..7e6ef14158b 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx @@ -10,6 +10,7 @@ import { useChainChecker, useGetChainPrefixBySlug, useGetNftContractSupportedCha import { upsertCustomToken, validateCustomToken } from '@subwallet/extension-koni-ui/messaging'; import { FormCallbacks, FormFieldData, ThemeProps } from '@subwallet/extension-koni-ui/types'; import { convertFieldToError, convertFieldToObject, reformatAddress, simpleCheckForm } from '@subwallet/extension-koni-ui/utils'; +import { reformatContractAddress } from '@subwallet/extension-koni-ui/utils/account/reformatContractAddress'; import { Form, Icon, Input } from '@subwallet/react-ui'; import { PlusCircle } from 'phosphor-react'; import { RuleObject } from 'rc-field-form/lib/interface'; @@ -18,7 +19,6 @@ import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; import { isAddress, isEthereumAddress } from '@polkadot/util-crypto'; -import {reformatContractAddress} from "@subwallet/extension-koni-ui/utils/account/reformatContractAddress"; type Props = ThemeProps; @@ -93,7 +93,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const empty = Object.entries(all).some(([key, value]) => key !== 'symbol' ? !value : false); - const { chain, type, contractAddress } = changes; + const { chain, contractAddress, type } = changes; if (chain) { const nftTypes = getNftTypeSupported(chainInfoMap[chain]); @@ -189,7 +189,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const contractAddressTransform = useCallback((contractAddress: string) => { return reformatContractAddress(selectedChain, contractAddress); - }, [selectedChain]) + }, [selectedChain]); const contractAddressValidator = useCallback((rule: RuleObject, contractAddress: string): Promise => { return new Promise((resolve, reject) => { @@ -300,7 +300,7 @@ function Component ({ className = '' }: Props): React.ReactElement { { const contractRules = useMemo((): FormRule[] => { return [ - ({ getFieldValue }) => ({ - transform: (contractAddress) => { + ({ getFieldValue }) => ({ + transform: (contractAddress: string) => { return reformatContractAddress(selectedChain, contractAddress); }, validator: (_, contractAddress: string) => { @@ -215,7 +215,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const all = convertFieldToObject(allFields); const allError = convertFieldToError(allFields); - const { chain, type, contractAddress } = changes; + const { chain, contractAddress, type } = changes; const baseResetFields = ['tokenName', 'symbol', 'decimals', 'priceId']; @@ -238,7 +238,7 @@ function Component ({ className = '' }: Props): React.ReactElement { } if (contractAddress) { - form.setFieldValue('contractAddress', reformatContractAddress(selectedChain, contractAddress)); + form.setFieldValue('contractAddress', reformatContractAddress(selectedChain, contractAddress)); } if (allError.contractAddress.length > 0 || allError.assetId.length > 0) { @@ -247,7 +247,7 @@ function Component ({ className = '' }: Props): React.ReactElement { setFieldDisabled(!all.chain || !all.type || allError.contractAddress.length > 0 || allError.assetId.length > 0); setIsDisabled(empty || error); - }, [chainInfoMap, form]); + }, [chainInfoMap, form, selectedChain]); const onSubmitContractAddress: FormCallbacks['onFinish'] = useCallback((formValues: TokenImportFormType) => { const { chain, contractAddress, decimals, priceId, symbol, tokenName, type } = formValues; diff --git a/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts b/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts index edaf1212c20..4c5eeb844d1 100644 --- a/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts +++ b/packages/extension-koni-ui/src/utils/account/reformatContractAddress.ts @@ -1,8 +1,9 @@ // Copyright 2019-2022 @polkadot/extension-ui authors & contributors // SPDX-License-Identifier: Apache-2.0 -import {isEthereumAddress} from "@polkadot/util-crypto"; -import {reformatAddress} from "@subwallet/extension-koni-ui/utils"; +import { reformatAddress } from '@subwallet/extension-koni-ui/utils'; + +import { isEthereumAddress } from '@polkadot/util-crypto'; const SPECIAL_CHAIN = ['rootstock']; From 660b59d0617700a4c476fce1c7dba884c506ae1b Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Tue, 21 Jan 2025 14:48:05 +0700 Subject: [PATCH 3/4] [Issue-3974] Fix lint --- packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx index 7e6ef14158b..0f8d626536f 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx @@ -121,7 +121,7 @@ function Component ({ className = '' }: Props): React.ReactElement { setNameDisabled(!all.chain || !all.type || allError.contractAddress.length > 0); setIsDisabled(empty || error); - }, [chainInfoMap, form]); + }, [chainInfoMap, form, selectedChain]); const onSubmit: FormCallbacks['onFinish'] = useCallback((formValues: NftImportFormType) => { const { chain, contractAddress, symbol, type } = formValues; From 630b9fcff0ddae2f7a9fbee5822f65aa07e9abb6 Mon Sep 17 00:00:00 2001 From: S2kael Date: Thu, 23 Jan 2025 14:37:34 +0700 Subject: [PATCH 4/4] [Issue-3974] Update hook dependency --- .../src/Popup/Home/Nfts/NftImport.tsx | 106 ++++++++++-------- .../Settings/Tokens/FungibleTokenImport.tsx | 8 +- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx index 0f8d626536f..ede8e2aa347 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx @@ -8,7 +8,7 @@ import { AddressInput, ChainSelector, Layout, PageWrapper, TokenTypeSelector } f import { DataContext } from '@subwallet/extension-koni-ui/contexts/DataContext'; import { useChainChecker, useGetChainPrefixBySlug, useGetNftContractSupportedChains, useNotification, useTranslation } from '@subwallet/extension-koni-ui/hooks'; import { upsertCustomToken, validateCustomToken } from '@subwallet/extension-koni-ui/messaging'; -import { FormCallbacks, FormFieldData, ThemeProps } from '@subwallet/extension-koni-ui/types'; +import { FormCallbacks, FormFieldData, FormRule, ThemeProps } from '@subwallet/extension-koni-ui/types'; import { convertFieldToError, convertFieldToObject, reformatAddress, simpleCheckForm } from '@subwallet/extension-koni-ui/utils'; import { reformatContractAddress } from '@subwallet/extension-koni-ui/utils/account/reformatContractAddress'; import { Form, Icon, Input } from '@subwallet/react-ui'; @@ -94,6 +94,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const empty = Object.entries(all).some(([key, value]) => key !== 'symbol' ? !value : false); const { chain, contractAddress, type } = changes; + const { chain: selectedChain } = all; if (chain) { const nftTypes = getNftTypeSupported(chainInfoMap[chain]); @@ -121,7 +122,7 @@ function Component ({ className = '' }: Props): React.ReactElement { setNameDisabled(!all.chain || !all.type || allError.contractAddress.length > 0); setIsDisabled(empty || error); - }, [chainInfoMap, form, selectedChain]); + }, [chainInfoMap, form]); const onSubmit: FormCallbacks['onFinish'] = useCallback((formValues: NftImportFormType) => { const { chain, contractAddress, symbol, type } = formValues; @@ -187,53 +188,62 @@ function Component ({ className = '' }: Props): React.ReactElement { }); }, [t]); - const contractAddressTransform = useCallback((contractAddress: string) => { - return reformatContractAddress(selectedChain, contractAddress); - }, [selectedChain]); - - const contractAddressValidator = useCallback((rule: RuleObject, contractAddress: string): Promise => { - return new Promise((resolve, reject) => { - if (!isAddress(contractAddress)) { - reject(t('Invalid contract address')); - } else { - const isValidEvmContract = [_AssetType.ERC721].includes(selectedNftType) && isEthereumAddress(contractAddress); - const isValidWasmContract = [_AssetType.PSP34].includes(selectedNftType) && isValidSubstrateAddress(contractAddress); - const reformattedAddress = reformatAddress(contractAddress, chainNetworkPrefix); - - if (isValidEvmContract || isValidWasmContract) { - setLoading(true); - validateCustomToken({ - contractAddress: reformattedAddress, - originChain: selectedChain, - type: selectedNftType - }) - .then((validationResult) => { - setLoading(false); - - if (validationResult.isExist) { - reject(t('Existed NFT')); - } - - if (validationResult.contractError) { - reject(t('Invalid contract for the selected chain')); - } - - if (!validationResult.isExist && !validationResult.contractError) { - form.setFieldValue('collectionName', validationResult.name); - form.setFieldValue('symbol', validationResult.symbol); - resolve(); + const contractRules = useMemo((): FormRule[] => { + return [ + ({ getFieldValue }) => ({ + transform: (contractAddress: string) => { + const selectedChain = getFieldValue('chain') as string; + + return reformatContractAddress(selectedChain, contractAddress); + }, + validator: (_, contractAddress: string): Promise => { + return new Promise((resolve, reject) => { + if (!isAddress(contractAddress)) { + reject(t('Invalid contract address')); + } else { + const selectedChain = getFieldValue('chain') as string; + const selectedNftType = getFieldValue('type') as _AssetType; + const isValidEvmContract = [_AssetType.ERC721].includes(selectedNftType) && isEthereumAddress(contractAddress); + const isValidWasmContract = [_AssetType.PSP34].includes(selectedNftType) && isValidSubstrateAddress(contractAddress); + const reformattedAddress = reformatAddress(contractAddress, chainNetworkPrefix); + + if (isValidEvmContract || isValidWasmContract) { + setLoading(true); + validateCustomToken({ + contractAddress: reformattedAddress, + originChain: selectedChain, + type: selectedNftType + }) + .then((validationResult) => { + setLoading(false); + + if (validationResult.isExist) { + reject(t('Existed NFT')); + } + + if (validationResult.contractError) { + reject(t('Invalid contract for the selected chain')); + } + + if (!validationResult.isExist && !validationResult.contractError) { + form.setFieldValue('collectionName', validationResult.name); + form.setFieldValue('symbol', validationResult.symbol); + resolve(); + } + }) + .catch(() => { + setLoading(false); + reject(t('Invalid contract for the selected chain')); + }); + } else { + reject(t('Invalid contract address')); } - }) - .catch(() => { - setLoading(false); - reject(t('Invalid contract for the selected chain')); - }); - } else { - reject(t('Invalid contract address')); + } + }); } - } - }); - }, [chainNetworkPrefix, form, selectedChain, selectedNftType, t]); + }) + ]; + }, [chainNetworkPrefix, form, t]); useEffect(() => { selectedChain && checkChain(selectedChain); @@ -300,7 +310,7 @@ function Component ({ className = '' }: Props): React.ReactElement { { return [ ({ getFieldValue }) => ({ transform: (contractAddress: string) => { + const selectedChain = getFieldValue('chain') as string; + return reformatContractAddress(selectedChain, contractAddress); }, validator: (_, contractAddress: string) => { return new Promise((resolve, reject) => { const selectedTokenType = getFieldValue('type') as _AssetType; + const selectedChain = getFieldValue('chain') as string; const isValidEvmContract = [_AssetType.ERC20].includes(selectedTokenType) && isEthereumAddress(contractAddress); const isValidWasmContract = [_AssetType.PSP22].includes(selectedTokenType) && isValidSubstrateAddress(contractAddress); @@ -160,7 +163,7 @@ function Component ({ className = '' }: Props): React.ReactElement { } }) ]; - }, [chainNetworkPrefix, form, selectedChain, t]); + }, [chainNetworkPrefix, form, t]); const assetIdRules = useMemo((): FormRule[] => { return [ @@ -216,6 +219,7 @@ function Component ({ className = '' }: Props): React.ReactElement { const allError = convertFieldToError(allFields); const { chain, contractAddress, type } = changes; + const { chain: selectedChain } = all; const baseResetFields = ['tokenName', 'symbol', 'decimals', 'priceId']; @@ -247,7 +251,7 @@ function Component ({ className = '' }: Props): React.ReactElement { setFieldDisabled(!all.chain || !all.type || allError.contractAddress.length > 0 || allError.assetId.length > 0); setIsDisabled(empty || error); - }, [chainInfoMap, form, selectedChain]); + }, [chainInfoMap, form]); const onSubmitContractAddress: FormCallbacks['onFinish'] = useCallback((formValues: TokenImportFormType) => { const { chain, contractAddress, decimals, priceId, symbol, tokenName, type } = formValues;