diff --git a/packages/controller-utils/src/util.test.ts b/packages/controller-utils/src/util.test.ts index bbf993af5cc..26e90b9da51 100644 --- a/packages/controller-utils/src/util.test.ts +++ b/packages/controller-utils/src/util.test.ts @@ -277,13 +277,33 @@ describe('util', () => { }); describe('toChecksumHexAddress', () => { - const fullAddress = `0x${VALID}`; - it('should return address for valid address', () => { - expect(util.toChecksumHexAddress(fullAddress)).toBe(fullAddress); + it('should return an 0x-prefixed checksum address untouched', () => { + const address = '0x4e1fF7229BDdAf0A73DF183a88d9c3a04cc975e0'; + expect(util.toChecksumHexAddress(address)).toBe(address); }); - it('should return address for non prefix address', () => { - expect(util.toChecksumHexAddress(VALID)).toBe(fullAddress); + it('should prefix a non-0x-prefixed checksum address with 0x', () => { + expect( + util.toChecksumHexAddress('4e1fF7229BDdAf0A73DF183a88d9c3a04cc975e0'), + ).toBe('0x4e1fF7229BDdAf0A73DF183a88d9c3a04cc975e0'); + }); + + it('should convert a non-checksum address to a checksum address', () => { + expect( + util.toChecksumHexAddress('0x4e1ff7229bddaf0a73df183a88d9c3a04cc975e0'), + ).toBe('0x4e1fF7229BDdAf0A73DF183a88d9c3a04cc975e0'); + }); + + it('should return "0x" if given an empty string', () => { + expect(util.toChecksumHexAddress('')).toBe('0x'); + }); + + it('should return the input untouched if it is undefined', () => { + expect(util.toChecksumHexAddress(undefined)).toBeUndefined(); + }); + + it('should return the input untouched if it is null', () => { + expect(util.toChecksumHexAddress(null)).toBeNull(); }); }); diff --git a/packages/controller-utils/src/util.ts b/packages/controller-utils/src/util.ts index ed2503cd087..c9bf11c9b2a 100644 --- a/packages/controller-utils/src/util.ts +++ b/packages/controller-utils/src/util.ts @@ -251,20 +251,45 @@ export async function safelyExecuteWithTimeout( } /** - * Convert an address to a checksummed hexidecimal address. + * Convert an address to a checksummed hexadecimal address. * * @param address - The address to convert. - * @returns A 0x-prefixed hexidecimal checksummed address, if address is valid. Otherwise original input 0x-prefixe, if address is valid. Otherwise original input 0x-prefixed. + * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid. */ -export function toChecksumHexAddress(address: string) { +export function toChecksumHexAddress(address: string): string; + +/** + * Convert an address to a checksummed hexadecimal address. + * + * Note that this particular overload does nothing. + * + * @param address - A value that is not a string (e.g. `undefined` or `null`). + * @returns The `address` untouched. + * @deprecated This overload is designed to gracefully handle an invalid input + * and is only present for backward compatibility. It may be removed in a future + * major version. Please pass a string to `toChecksumHexAddress` instead. + */ +export function toChecksumHexAddress(address: T): T; + +// Tools only see JSDocs for overloads and ignore them for the implementation. +// eslint-disable-next-line jsdoc/require-jsdoc +export function toChecksumHexAddress(address: unknown) { + if (typeof address !== 'string') { + // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this + // function was previously using) for backward compatibility. + return address; + } + const hexPrefixed = add0x(address); + if (!isHexString(hexPrefixed)) { - // Version 5.1 of ethereumjs-utils would have returned '0xY' for input 'y' + // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y' // but we shouldn't waste effort trying to change case on a clearly invalid // string. Instead just return the hex prefixed original string which most // closely mimics the original behavior. return hexPrefixed; } + return toChecksumAddress(hexPrefixed); } diff --git a/packages/preferences-controller/src/PreferencesController.ts b/packages/preferences-controller/src/PreferencesController.ts index 2bf761950a4..b7451b2c27f 100644 --- a/packages/preferences-controller/src/PreferencesController.ts +++ b/packages/preferences-controller/src/PreferencesController.ts @@ -254,7 +254,9 @@ export class PreferencesController extends BaseController< * @param addresses - List of addresses to use to generate new identities. */ addIdentities(addresses: string[]) { - const checksummedAddresses = addresses.map(toChecksumHexAddress); + const checksummedAddresses = addresses.map((address) => + toChecksumHexAddress(address), + ); this.update((state) => { const { identities } = state; for (const address of checksummedAddresses) {