diff --git a/shared/modules/network.utils.test.ts b/shared/modules/network.utils.test.ts new file mode 100644 index 000000000..ee4ef3f83 --- /dev/null +++ b/shared/modules/network.utils.test.ts @@ -0,0 +1,86 @@ +import { MAX_SAFE_CHAIN_ID } from '../constants/network'; +import { + isSafeChainId, + isPrefixedFormattedHexString, + isTokenDetectionEnabledForNetwork, +} from './network.utils'; + +describe('network utils', () => { + describe('isSafeChainId', () => { + it('returns true given an integer greater than 0 and less than or equal to the max safe chain ID', () => { + expect(isSafeChainId(3)).toBe(true); + }); + + it('returns true given the max safe chain ID', () => { + expect(isSafeChainId(MAX_SAFE_CHAIN_ID)).toBe(true); + }); + + it('returns false given something other than an integer', () => { + expect(isSafeChainId('not-an-integer')).toBe(false); + }); + + it('returns false given a negative integer', () => { + expect(isSafeChainId(-1)).toBe(false); + }); + + it('returns false given an integer greater than the max safe chain ID', () => { + expect(isSafeChainId(MAX_SAFE_CHAIN_ID + 1)).toBe(false); + }); + }); + + describe('isPrefixedFormattedHexString', () => { + it('returns true given a string that matches a hex number formatted as a "0x"-prefixed, non-zero, non-zero-padded string', () => { + expect(isPrefixedFormattedHexString('0x1')).toBe(true); + expect(isPrefixedFormattedHexString('0xa')).toBe(true); + expect(isPrefixedFormattedHexString('0xabc123')).toBe(true); + }); + + it('returns true given a "0x"-prefixed hex string that contains uppercase characters', () => { + expect(isPrefixedFormattedHexString('0XABC123')).toBe(true); + }); + + it('returns false given a "0x"-prefixed hex string that evaluates to zero', () => { + expect(isPrefixedFormattedHexString('0x0')).toBe(false); + }); + + it('returns false given a "0x"-prefixed hex string that does not evaluate to zero but is zero-padded', () => { + expect(isPrefixedFormattedHexString('0x01')).toBe(false); + }); + + it('returns false given a hex number that is simply a string but not "0x"-prefixed', () => { + expect(isPrefixedFormattedHexString('abc123')).toBe(false); + }); + + it('returns false if given something other than a string', () => { + expect(isPrefixedFormattedHexString({ something: 'else' })).toBe(false); + }); + }); + + describe('isTokenDetectionEnabledForNetwork', () => { + it('returns true given the chain ID for Mainnet', () => { + expect(isTokenDetectionEnabledForNetwork('0x1')).toBe(true); + }); + + it('returns true given the chain ID for BSC', () => { + expect(isTokenDetectionEnabledForNetwork('0x38')).toBe(true); + }); + + it('returns true given the chain ID for Polygon', () => { + expect(isTokenDetectionEnabledForNetwork('0x89')).toBe(true); + }); + + it('returns true given the chain ID for Avalanche', () => { + expect(isTokenDetectionEnabledForNetwork('0xa86a')).toBe(true); + }); + + it('returns false given a string that is not the chain ID for Mainnet, BSC, Polygon, or Avalanche', () => { + expect(isTokenDetectionEnabledForNetwork('some other chain ID')).toBe( + false, + ); + }); + + it('returns false given undefined', () => { + expect(isTokenDetectionEnabledForNetwork(undefined)).toBe(false); + }); + }); +}); diff --git a/shared/modules/network.utils.js b/shared/modules/network.utils.ts similarity index 52% rename from shared/modules/network.utils.js rename to shared/modules/network.utils.ts index 05723b3ac..13fca471d 100644 --- a/shared/modules/network.utils.js +++ b/shared/modules/network.utils.ts @@ -5,24 +5,22 @@ import { CHAIN_IDS, MAX_SAFE_CHAIN_ID } from '../constants/network'; * Because some cryptographic libraries we use expect the chain ID to be a * number primitive, it must not exceed a certain size. * - * @param {number} chainId - The chain ID to check for safety. - * @returns {boolean} Whether the given chain ID is safe. + * @param chainId - The chain ID to check for safety. + * @returns Whether the given chain ID is safe. */ -export function isSafeChainId(chainId) { - return ( - Number.isSafeInteger(chainId) && chainId > 0 && chainId <= MAX_SAFE_CHAIN_ID - ); +export function isSafeChainId(chainId: unknown): boolean { + return isSafeInteger(chainId) && chainId > 0 && chainId <= MAX_SAFE_CHAIN_ID; } /** * Checks whether the given value is a 0x-prefixed, non-zero, non-zero-padded, * hexadecimal string. * - * @param {any} value - The value to check. - * @returns {boolean} True if the value is a correctly formatted hex string, + * @param value - The value to check. + * @returns True if the value is a correctly formatted hex string, * false otherwise. */ -export function isPrefixedFormattedHexString(value) { +export function isPrefixedFormattedHexString(value: unknown) { if (typeof value !== 'string') { return false; } @@ -35,7 +33,7 @@ export function isPrefixedFormattedHexString(value) { * @param chainId - ChainID of network * @returns Whether the current network supports token detection */ -export function isTokenDetectionEnabledForNetwork(chainId) { +export function isTokenDetectionEnabledForNetwork(chainId: string | undefined) { switch (chainId) { case CHAIN_IDS.MAINNET: case CHAIN_IDS.BSC: @@ -46,3 +44,14 @@ export function isTokenDetectionEnabledForNetwork(chainId) { return false; } } + +/** + * Like {@link Number.isSafeInteger}, but types the input as a `number` if it is + * indeed a safe integer. + * + * @param value - The value to check. + * @returns True if the value is a safe integer, false otherwise. + */ +function isSafeInteger(value: unknown): value is number { + return Number.isSafeInteger(value); +}