diff --git a/packages/extension-base/src/services/chain-service/index.ts b/packages/extension-base/src/services/chain-service/index.ts index a098d6d532c..179c2a49cb0 100644 --- a/packages/extension-base/src/services/chain-service/index.ts +++ b/packages/extension-base/src/services/chain-service/index.ts @@ -1924,9 +1924,7 @@ export class ChainService { let existedToken: _ChainAsset | undefined; for (const token of Object.values(assetRegistry)) { - const ticker = token?.slug; - - if (ticker === data.ticker && token.assetType === data.type && token.originChain === data.originChain) { + if (token?.symbol === data.ticker && token?.assetType === data.type && token?.originChain === data.originChain) { existedToken = token; break; } diff --git a/packages/extension-base/src/services/hiro-service/utils/index.ts b/packages/extension-base/src/services/hiro-service/utils/index.ts index d668584ab55..70448d5e49b 100644 --- a/packages/extension-base/src/services/hiro-service/utils/index.ts +++ b/packages/extension-base/src/services/hiro-service/utils/index.ts @@ -86,3 +86,17 @@ export function getPreviewUrl (inscriptionId: string) { throw error; } } + +export function isValidBrc20Ticker (ticker: string) { + const bytesLength = getByteLength(ticker); + + return bytesLength === 4 || bytesLength === 5; +} + +function getByteLength (str: string): number { + const encoder = new TextEncoder(); + const encodedStr = encoder.encode(str); + + // Return the length of the encoded array, which represents the number of bytes + return encodedStr.length; +} diff --git a/packages/extension-base/src/services/rune-service/utils/index.ts b/packages/extension-base/src/services/rune-service/utils/index.ts index ad2995eed85..78657ad4f1c 100644 --- a/packages/extension-base/src/services/rune-service/utils/index.ts +++ b/packages/extension-base/src/services/rune-service/utils/index.ts @@ -42,13 +42,17 @@ export async function getAllCollectionRunes (isTestnet = false) { } } -export async function getRuneMetadata (runeid: string, isTestnet = false) { +export async function getRuneMetadata (runeId: string, isTestnet = false) { const runeService = RunesService.getInstance(isTestnet); try { - return await runeService.getRuneMetadata(runeid); + return await runeService.getRuneMetadata(runeId); } catch (error) { - console.error(`Failed to get rune ${runeid} metadata`, error); + console.error(`Failed to get rune ${runeId} metadata`, error); throw error; } } + +export function isValidRuneId (runeId: string) { + return runeId.includes(':'); +} diff --git a/packages/extension-koni-ui/src/Popup/Settings/Tokens/FungibleTokenImport.tsx b/packages/extension-koni-ui/src/Popup/Settings/Tokens/FungibleTokenImport.tsx index 4006e059e1d..f958bee9f10 100644 --- a/packages/extension-koni-ui/src/Popup/Settings/Tokens/FungibleTokenImport.tsx +++ b/packages/extension-koni-ui/src/Popup/Settings/Tokens/FungibleTokenImport.tsx @@ -3,6 +3,8 @@ import { _AssetType, _ChainInfo } from '@subwallet/chain-list/types'; import { _getTokenTypesSupportedByChain, _isChainTestNet, _parseMetadataForBrc20Asset, _parseMetadataForRuneAsset, _parseMetadataForSmartContractAsset } from '@subwallet/extension-base/services/chain-service/utils'; +import { isValidBrc20Ticker } from '@subwallet/extension-base/services/hiro-service/utils'; +import { isValidRuneId } from '@subwallet/extension-base/services/rune-service/utils'; import { isValidSubstrateAddress } from '@subwallet/extension-base/utils'; import { AddressInput, ChainSelector, Layout, PageWrapper, TokenTypeSelector } from '@subwallet/extension-koni-ui/components'; import { DataContext } from '@subwallet/extension-koni-ui/contexts/DataContext'; @@ -10,7 +12,6 @@ import { useChainChecker, useDefaultNavigate, useGetChainPrefixBySlug, useGetFun import { upsertCustomToken, validateCustomBrc20, validateCustomRune, validateCustomToken } from '@subwallet/extension-koni-ui/messaging'; import { FormCallbacks, FormRule, Theme, ThemeProps } from '@subwallet/extension-koni-ui/types'; import { convertFieldToError, convertFieldToObject, reformatAddress, simpleCheckForm } from '@subwallet/extension-koni-ui/utils'; -import { isBitcoinAddress } from '@subwallet/keyring'; import { Col, Field, Form, Icon, Input, Row } from '@subwallet/react-ui'; import SwAvatar from '@subwallet/react-ui/es/sw-avatar'; import { PlusCircle } from 'phosphor-react'; @@ -114,11 +115,12 @@ function Component ({ className = '' }: Props): React.ReactElement { const selectedTokenType = getFieldValue('type') as _AssetType; const isValidEvmContract = [_AssetType.ERC20].includes(selectedTokenType) && isEthereumAddress(inputMetadata); const isValidWasmContract = [_AssetType.PSP22].includes(selectedTokenType) && isValidSubstrateAddress(inputMetadata); - const isValidRune = [_AssetType.RUNE].includes(selectedTokenType) && isBitcoinAddress(inputMetadata); - const isValidBrc20 = [_AssetType.BRC20].includes(selectedTokenType) && isBitcoinAddress(inputMetadata); - const reformattedContractAddress = reformatAddress(inputMetadata, chainNetworkPrefix); + const isValidRune = [_AssetType.RUNE].includes(selectedTokenType) && isValidRuneId(inputMetadata); + const isValidBrc20 = [_AssetType.BRC20].includes(selectedTokenType) && isValidBrc20Ticker(inputMetadata); if (isValidEvmContract || isValidWasmContract) { + const reformattedContractAddress = reformatAddress(inputMetadata, chainNetworkPrefix); + setLoading(true); validateCustomToken({ contractAddress: reformattedContractAddress, @@ -158,7 +160,6 @@ function Component ({ className = '' }: Props): React.ReactElement { type: selectedTokenType }) .then((validationResult) => { - console.log('validationResult'); setLoading(false); if (validationResult.isExist) {