From ae08035d5dbaead6ec920a2cf743512092299e61 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Fri, 31 Mar 2023 10:52:56 -0600 Subject: [PATCH] Convert shared/modules/network.utils to TS (#18352) We want to convert NetworkController to TypeScript in order to be able to compare differences in the controller between in this repo and the core repo. To do this, however, we need to convert the dependencies of the controller to TypeScript. As a part of this effort, this commit converts `shared/modules/network.utils.js` to TypeScript, and also adds tests. Co-authored-by: Mark Stacey --- shared/modules/network.utils.test.ts | 86 +++++++++++++++++++ .../{network.utils.js => network.utils.ts} | 29 ++++--- 2 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 shared/modules/network.utils.test.ts rename shared/modules/{network.utils.js => network.utils.ts} (52%) 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); +}