From 7f821be1a3478e5db6df94a1110e0ef0145b72a9 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 29 Aug 2023 22:17:45 -0400 Subject: [PATCH] replace Number.parseint instances --- src/AssetsTransferApi.ts | 18 ++++----- src/createXcmTypes/ParaToSystem.ts | 16 ++++---- src/createXcmTypes/SystemToPara.ts | 6 +-- src/createXcmTypes/SystemToSystem.ts | 22 +++++------ src/createXcmTypes/util/getAssetId.ts | 10 ++--- .../util/sortMultiAssetsAscending.ts | 21 +++++------ src/errors/checkXcmTxInputs.ts | 37 +++++++------------ src/testHelpers/adjustedMockSystemApi.ts | 25 ++++++++++--- src/types.ts | 3 +- 9 files changed, 79 insertions(+), 79 deletions(-) diff --git a/src/AssetsTransferApi.ts b/src/AssetsTransferApi.ts index 14c61bbc..efee5a83 100644 --- a/src/AssetsTransferApi.ts +++ b/src/AssetsTransferApi.ts @@ -10,6 +10,7 @@ import type { RuntimeDispatchInfoV1, } from '@polkadot/types/interfaces'; import type { ISubmittableResult } from '@polkadot/types/types'; +import BN from 'bn.js'; import { RELAY_CHAIN_IDS, @@ -62,6 +63,7 @@ import { TxResult, UnsignedTransaction, } from './types'; +import { validateNumber } from './validate'; /** * Holds open an api connection to a specified chain within the ApiPromise in order to help @@ -886,7 +888,7 @@ export class AssetsTransferApi { opts: { paysWithFeeOrigin?: string; sendersAddr: string } ): Promise<`0x${string}`> => { const { paysWithFeeOrigin, sendersAddr } = opts; - let assetId = 0; + let assetId = new BN(0); // if a paysWithFeeOrigin is provided and the chain is of system origin // we assign the assetId to the value of paysWithFeeOrigin @@ -895,21 +897,21 @@ export class AssetsTransferApi { ); if (paysWithFeeOrigin && isOriginSystemParachain) { - assetId = Number.parseInt(paysWithFeeOrigin); - const isNotANumber = Number.isNaN(assetId); + const isValidInt = validateNumber(paysWithFeeOrigin); - if (isNotANumber) { + if (!isValidInt) { throw new BaseError( `paysWithFeeOrigin value must be a valid number. Received: ${paysWithFeeOrigin}`, BaseErrorsEnum.InvalidInput ); } + assetId = new BN(paysWithFeeOrigin); const isSufficient = await this.checkAssetIsSufficient(assetId); if (!isSufficient) { throw new BaseError( - `asset with assetId ${assetId} is not a sufficient asset to pay for fees`, + `asset with assetId ${assetId.toString()} is not a sufficient asset to pay for fees`, BaseErrorsEnum.InvalidAsset ); } @@ -970,9 +972,7 @@ export class AssetsTransferApi { * @param assetId number * @returns Promise */ - private checkAssetIsSufficient = async ( - assetId: number - ): Promise => { + private checkAssetIsSufficient = async (assetId: BN): Promise => { try { const asset = (await this._api.query.assets.asset(assetId)).unwrap(); @@ -983,7 +983,7 @@ export class AssetsTransferApi { return false; } catch (err: unknown) { throw new BaseError( - `assetId ${assetId} does not match a valid asset`, + `assetId ${assetId.toString()} does not match a valid asset`, BaseErrorsEnum.InvalidAsset ); } diff --git a/src/createXcmTypes/ParaToSystem.ts b/src/createXcmTypes/ParaToSystem.ts index 03db694c..547ba9c0 100644 --- a/src/createXcmTypes/ParaToSystem.ts +++ b/src/createXcmTypes/ParaToSystem.ts @@ -24,6 +24,7 @@ import { } from '../types'; import { getFeeAssetItemIndex } from '../util/getFeeAssetItemIndex'; import { normalizeArrToStr } from '../util/normalizeArrToStr'; +import { validateNumber } from '../validate'; import type { CreateAssetsOpts, CreateFeeAssetItemOpts, @@ -289,12 +290,11 @@ export const ParaToSystem: ICreateXcmType = { const { registry } = opts; const { xcAssets } = registry; const { tokens: relayTokens } = registry.currentRelayRegistry['0']; - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const isNotANumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); const isRelayNative = isRelayNativeAsset(relayTokens, assetId); const currentRelayChainSpecName = registry.relayChain; - if (!isRelayNative && isNotANumber) { + if (!isRelayNative && !isValidInt) { assetId = await getAssetId(api, registry, assetId, specName); } @@ -407,10 +407,9 @@ const createXTokensMultiAssets = async ( const amount = amounts[i]; let assetId = assets[i]; - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const isNotANumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); - if (isNotANumber) { + if (!isValidInt) { assetId = await getAssetId(api, registry, assetId, specName); } @@ -516,10 +515,9 @@ const createParaToSystemMultiAssets = async ( const amount = amounts[i]; let assetId = assets[i]; - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const isNotANumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); - if (isNotANumber) { + if (!isValidInt) { assetId = await getAssetId( api, registry, diff --git a/src/createXcmTypes/SystemToPara.ts b/src/createXcmTypes/SystemToPara.ts index c9779f36..56197a7c 100644 --- a/src/createXcmTypes/SystemToPara.ts +++ b/src/createXcmTypes/SystemToPara.ts @@ -19,6 +19,7 @@ import type { Registry } from '../registry'; import { MultiAsset } from '../types'; import { getFeeAssetItemIndex } from '../util/getFeeAssetItemIndex'; import { normalizeArrToStr } from '../util/normalizeArrToStr'; +import { validateNumber } from '../validate'; import { CreateAssetsOpts, CreateFeeAssetItemOpts, @@ -297,11 +298,10 @@ export const createSystemToParaMultiAssets = async ( let assetId: string = assets[i]; const amount = amounts[i]; - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const isNotANumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); const isRelayNative = isRelayNativeAsset(tokens, assetId); - if (!isRelayNative && isNotANumber) { + if (!isRelayNative && !isValidInt) { assetId = await getAssetId( api, registry, diff --git a/src/createXcmTypes/SystemToSystem.ts b/src/createXcmTypes/SystemToSystem.ts index dad05b72..906b636d 100644 --- a/src/createXcmTypes/SystemToSystem.ts +++ b/src/createXcmTypes/SystemToSystem.ts @@ -18,6 +18,7 @@ import { BaseError, BaseErrorsEnum } from '../errors'; import type { Registry } from '../registry'; import { getFeeAssetItemIndex } from '../util/getFeeAssetItemIndex'; import { normalizeArrToStr } from '../util/normalizeArrToStr'; +import { validateNumber } from '../validate'; import { MultiAsset } from './../types'; import { CreateAssetsOpts, @@ -289,20 +290,17 @@ export const createSystemToSystemMultiAssets = async ( let assetId: string = assets[i]; const amount = amounts[i]; - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const isNotANumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); const isRelayNative = isRelayNativeAsset(tokens, assetId); - if (!isRelayNative) { - if (isNotANumber) { - assetId = await getAssetId( - api, - registry, - assetId, - specName, - isForeignAssetsTransfer - ); - } + if (!isRelayNative && !isValidInt) { + assetId = await getAssetId( + api, + registry, + assetId, + specName, + isForeignAssetsTransfer + ); } let concretMultiLocation: MultiLocation; diff --git a/src/createXcmTypes/util/getAssetId.ts b/src/createXcmTypes/util/getAssetId.ts index 4e4e1100..fba8bea4 100644 --- a/src/createXcmTypes/util/getAssetId.ts +++ b/src/createXcmTypes/util/getAssetId.ts @@ -5,6 +5,7 @@ import { ApiPromise } from '@polkadot/api'; import { ASSET_HUB_CHAIN_ID } from '../../consts'; import { BaseError, BaseErrorsEnum } from '../../errors'; import { Registry } from '../../registry'; +import { validateNumber } from '../../validate'; import { foreignAssetMultiLocationIsInCacheOrRegistry } from './foreignAssetMultiLocationIsInCacheOrRegistry'; import { foreignAssetsMultiLocationExists } from './foreignAssetsMultiLocationExists'; import { getChainIdBySpecName } from './getChainIdBySpecName'; @@ -29,8 +30,7 @@ export const getAssetId = async ( isForeignAssetsTransfer?: boolean ): Promise => { const currentChainId = getChainIdBySpecName(registry, specName); - const parsedAssetAsNumber = Number.parseInt(asset); - const assetIsNumber = !Number.isNaN(parsedAssetAsNumber); + const assetIsValidInt = validateNumber(asset); const isParachain = parseInt(currentChainId) >= 2000; // if assets pallet, check the cache and return the cached assetId if found @@ -56,7 +56,7 @@ export const getAssetId = async ( } } // check number assetId in registry - if (assetIsNumber) { + if (assetIsValidInt) { // if assetId index is valid, return the assetId if (assetsInfo[asset] && assetsInfo[asset].length > 0) { return asset; @@ -105,7 +105,7 @@ export const getAssetId = async ( const { tokens } = registry.currentRelayRegistry[ASSET_HUB_CHAIN_ID]; assetId = tokens[0]; - } else if (assetIsNumber) { + } else if (assetIsValidInt) { const maybeAsset = await _api.query.assets.asset(asset); if (maybeAsset.isSome) { @@ -130,7 +130,7 @@ export const getAssetId = async ( ); } } else if (isParachain) { - if (!assetIsNumber) { + if (!assetIsValidInt) { // if not assetHub and assetId isnt a number, query the parachain chain for the asset symbol const parachainAssets = await _api.query.assets.asset.entries(); diff --git a/src/createXcmTypes/util/sortMultiAssetsAscending.ts b/src/createXcmTypes/util/sortMultiAssetsAscending.ts index 4b79b024..d321b438 100644 --- a/src/createXcmTypes/util/sortMultiAssetsAscending.ts +++ b/src/createXcmTypes/util/sortMultiAssetsAscending.ts @@ -2,8 +2,10 @@ import { JunctionV1 } from '@polkadot/types/interfaces'; import { ITuple } from '@polkadot/types-codec/types'; +import { BN } from 'bn.js'; import { MultiAsset, XcmMultiAsset } from '../../types'; +import { validateNumber } from '../../validate'; /** * This sorts a list of multiassets in ascending order based on their id. @@ -192,22 +194,17 @@ const getSortOrderForX2ThroughX8 = ( // if the junctions are the same type but not equal // we compare the inner values in order to determine sort order if (junctionA.type === junctionB.type && !junctionA.eq(junctionB)) { - const junctionAValueAsNumber = Number.parseInt( - junctionA.value.toString() - ); - const junctionAIsNotANumber = Number.isNaN(junctionAValueAsNumber); - - const junctionBValueAsNumber = Number.parseInt( - junctionB.value.toString() - ); - const junctionBIsNotANumber = Number.isNaN(junctionBValueAsNumber); + const junctionAIsValidInt = validateNumber(junctionA.value.toString()); + const junctionBIsValidInt = validateNumber(junctionB.value.toString()); // compare number values if both junction values are valid integers // otherwise compare the lexicographical values - if (!junctionAIsNotANumber && !junctionBIsNotANumber) { - if (junctionAValueAsNumber < junctionBValueAsNumber) { + if (junctionAIsValidInt && junctionBIsValidInt) { + const junctionAValueAsBN = new BN(junctionA.value.toString()); + const junctionBValueAsBN = new BN(junctionB.value.toString()); + if (junctionAValueAsBN.lt(junctionBValueAsBN)) { return -1; - } else if (junctionAValueAsNumber > junctionBValueAsNumber) { + } else if (junctionAValueAsBN.gt(junctionBValueAsBN)) { return 1; } } else { diff --git a/src/errors/checkXcmTxInputs.ts b/src/errors/checkXcmTxInputs.ts index 30b05ba6..ef1a2ed4 100644 --- a/src/errors/checkXcmTxInputs.ts +++ b/src/errors/checkXcmTxInputs.ts @@ -15,6 +15,7 @@ import { Registry } from '../registry'; import type { ChainInfo, ChainInfoKeys } from '../registry/types'; import { XCMChainInfoKeys } from '../registry/types'; import { AssetInfo, Direction } from '../types'; +import { validateNumber } from '../validate'; import { BaseError, BaseErrorsEnum } from './BaseError'; /** @@ -377,11 +378,8 @@ export const checkLiquidTokenValidity = async ( systemParachainInfo: ChainInfoKeys, assetId: string ) => { - // check if assetId is a number - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const invalidNumber = Number.isNaN(parsedAssetIdAsNumber); - - if (invalidNumber) { + const isValidInt = validateNumber(assetId); + if (!isValidInt) { throw new BaseError( `Liquid Tokens must be valid Integers`, BaseErrorsEnum.InvalidAsset @@ -475,11 +473,9 @@ const checkSystemAssets = async ( } else if (isLiquidTokenTransfer) { await checkLiquidTokenValidity(api, registry, systemParachainInfo, assetId); } else { - // check if assetId is a number - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const invalidNumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); - if (!invalidNumber) { + if (isValidInt) { let assetSymbol: string | undefined; // check the cache for the asset @@ -492,7 +488,7 @@ const checkSystemAssets = async ( if (!assetSymbol) { // if asset is not in cache or registry, query the assets pallet to see if it has a value - const asset = await api.query.assets.asset(parsedAssetIdAsNumber); + const asset = await api.query.assets.asset(assetId); // if asset is found in the assets pallet, return LocalTxType Assets if (asset.isNone) { @@ -501,9 +497,7 @@ const checkSystemAssets = async ( BaseErrorsEnum.AssetNotFound ); } else { - const assetSymbol = ( - await api.query.assets.metadata(parsedAssetIdAsNumber) - ).symbol + const assetSymbol = (await api.query.assets.metadata(assetId)).symbol .toHuman() ?.toString(); @@ -614,11 +608,9 @@ export const checkParaAssets = async ( const { xcAssets } = registry; const currentRelayChainSpecName = registry.relayChain; - // check if assetId is a number - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const invalidNumber = Number.isNaN(parsedAssetIdAsNumber); + const isValidInt = validateNumber(assetId); - if (!invalidNumber) { + if (isValidInt) { // query the parachains assets pallet to see if it has a value matching the assetId const asset = await api.query.assets.asset(assetId); @@ -666,11 +658,12 @@ export const checkParaAssets = async ( } else { // not a valid number // check if id is a valid token symbol of the system parachain chain - if (!invalidNumber) { + // TODO: Im confused about this, clarify this logic. + if (isValidInt) { // if assetId is not in registry cache, query for the asset if (!registry.cacheLookupAsset(assetId)) { // query the parachains assets pallet to see if it has a value matching the assetId - const asset = await api.query.assets.asset(parsedAssetIdAsNumber); + const asset = await api.query.assets.asset(assetId); if (asset.isNone) { throw new BaseError( @@ -939,10 +932,8 @@ export const checkAssetIdsAreOfSameAssetIdType = (assetIds: string[]) => { continue; } - const parsedAssetIdAsNumber = Number.parseInt(assetId); - const isNotANumber = Number.isNaN(parsedAssetIdAsNumber); - - if (!isNotANumber) { + const isValidInt = validateNumber(assetId); + if (isValidInt) { integerAssetIdFound = assetId; } else if (assetId.toLowerCase().includes('parents')) { multiLocationAssetIdFound = assetId; diff --git a/src/testHelpers/adjustedMockSystemApi.ts b/src/testHelpers/adjustedMockSystemApi.ts index d8dd6557..b365d78f 100644 --- a/src/testHelpers/adjustedMockSystemApi.ts +++ b/src/testHelpers/adjustedMockSystemApi.ts @@ -11,6 +11,7 @@ import type { } from '@polkadot/types/lookup'; import { ITuple } from '@polkadot/types-codec/types'; import { getSpecTypes } from '@polkadot/types-known'; +import BN from 'bn.js'; import { assetHubWestendV9435 } from './metadata/assetHubWestendV9435'; import { mockSystemApi } from './mockSystemApi'; @@ -104,7 +105,9 @@ const multiLocationAssetInfo = { status: mockSystemApi.registry.createType('PalletAssetsAssetStatus', 'live'), }; -const asset = (assetId: number): Promise> => +const asset = ( + assetId: number | string | BN +): Promise> => Promise.resolve().then(() => { const assets: Map = new Map(); @@ -149,7 +152,12 @@ const asset = (assetId: number): Promise> => ); assets.set(1984, sufficientAsset); - const maybeAsset = assets.has(assetId) ? assets.get(assetId) : undefined; + const adjAsset = BN.isBN(assetId) + ? assetId.toNumber() + : typeof assetId === 'string' + ? Number.parseInt(assetId) + : assetId; + const maybeAsset = assets.has(adjAsset) ? assets.get(adjAsset) : undefined; if (maybeAsset) { return new Option( @@ -165,7 +173,9 @@ const asset = (assetId: number): Promise> => ); }); -const assetsMetadata = (assetId: number): Promise => +const assetsMetadata = ( + assetId: number | string | BN +): Promise => Promise.resolve().then(() => { const metadata: Map = new Map(); @@ -187,8 +197,13 @@ const assetsMetadata = (assetId: number): Promise => ); metadata.set(1984, usdtMetadata); - const maybeMetadata = metadata.has(assetId) - ? metadata.get(assetId) + const adjAsset = BN.isBN(assetId) + ? assetId.toNumber() + : typeof assetId === 'string' + ? Number.parseInt(assetId) + : assetId; + const maybeMetadata = metadata.has(adjAsset) + ? metadata.get(adjAsset) : undefined; if (maybeMetadata) { diff --git a/src/types.ts b/src/types.ts index bacb57d7..fa1b7719 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,6 +8,7 @@ import { MultiLocation, } from '@polkadot/types/interfaces'; import type { ISubmittableResult } from '@polkadot/types/types'; +import BN from 'bn.js'; import type { ChainInfoRegistry } from './registry/types'; @@ -315,7 +316,7 @@ export interface UnsignedTransaction extends SignerPayloadJSON { * * @default 0 */ - assetId?: number; + assetId: BN; } export interface LocalDest {