diff --git a/src/util.ts b/src/util.ts index 926cbfcdf01..81a990ce291 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,5 @@ import { addHexPrefix, isValidAddress, bufferToHex } from 'ethereumjs-util'; +import { ethErrors } from 'eth-rpc-errors'; import { TYPED_MESSAGE_SCHEMA, typedSignatureHash } from 'eth-sig-util'; import { Transaction, FetchAllOptions } from './transaction/TransactionController'; import { MessageParams } from './message-manager/MessageManager'; @@ -340,16 +341,20 @@ export function validateTypedSignMessageDataV3(messageData: TypedMessageParams) export function validateTokenToWatch(token: Token) { const { address, symbol, decimals } = token; if (!address || !symbol || typeof decimals === 'undefined') { - throw new Error(`Cannot suggest token without address, symbol, and decimals`); + throw ethErrors.rpc.invalidParams(`Must specify address, symbol, and decimals.`); } - if (!(symbol.length < 7)) { - throw new Error(`Invalid symbol ${symbol} more than six characters`); + if (typeof symbol !== 'string') { + throw ethErrors.rpc.invalidParams(`Invalid symbol: not a string.`); } - if (isNaN(decimals) || decimals > 36 || decimals < 0) { - throw new Error(`Invalid decimals ${decimals} must be at least 0, and not over 36`); + if (symbol.length > 6) { + throw ethErrors.rpc.invalidParams(`Invalid symbol "${symbol}": longer than 6 characters.`); + } + const numDecimals = parseInt((decimals as unknown) as string, 10); + if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { + throw ethErrors.rpc.invalidParams(`Invalid decimals "${decimals}": must be 0 <= 36.`); } if (!isValidAddress(address)) { - throw new Error(`Invalid address ${address}`); + throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`); } } diff --git a/tests/util.test.ts b/tests/util.test.ts index 6f953f58b3a..dfcc20d3099 100644 --- a/tests/util.test.ts +++ b/tests/util.test.ts @@ -371,21 +371,31 @@ describe('util', () => { decimals: 0, symbol: 'TKN', } as any), - ).toThrow('Cannot suggest token without address, symbol, and decimals'); + ).toThrow('Must specify address, symbol, and decimals.'); expect(() => util.validateTokenToWatch({ address: '0x1', decimals: 0, symbol: undefined, } as any), - ).toThrow('Cannot suggest token without address, symbol, and decimals'); + ).toThrow('Must specify address, symbol, and decimals.'); expect(() => util.validateTokenToWatch({ address: '0x1', decimals: undefined, symbol: 'TKN', } as any), - ).toThrow('Cannot suggest token without address, symbol, and decimals'); + ).toThrow('Must specify address, symbol, and decimals.'); + }); + + it('should throw if symbol is not a string', () => { + expect(() => + util.validateTokenToWatch({ + address: '0xe9f786dfdd9be4d57e830acb52296837765f0e5b', + decimals: 0, + symbol: { foo: 'bar' }, + } as any), + ).toThrow('Invalid symbol: not a string.'); }); it('should throw if symbol is more than 6 characters long', () => { @@ -395,7 +405,7 @@ describe('util', () => { decimals: 0, symbol: 'TKNTKNTKN', } as any), - ).toThrow('Invalid symbol TKNTKNTKN more than six characters'); + ).toThrow('Invalid symbol "TKNTKNTKN": longer than 6 characters.'); }); it('should throw if invalid decimals', () => { @@ -412,14 +422,14 @@ describe('util', () => { decimals: 38, symbol: 'TKN', } as any), - ).toThrow('Invalid decimals 38 must be at least 0, and not over 36'); + ).toThrow('Invalid decimals "38": must be 0 <= 36.'); expect(() => util.validateTokenToWatch({ address: '0xe9f786dfdd9be4d57e830acb52296837765f0e5b', decimals: -1, symbol: 'TKN', } as any), - ).toThrow('Invalid decimals -1 must be at least 0, and not over 36'); + ).toThrow('Invalid decimals "-1": must be 0 <= 36.'); }); it('should throw if invalid address', () => { @@ -429,7 +439,7 @@ describe('util', () => { decimals: 0, symbol: 'TKN', } as any), - ).toThrow('Invalid address 0xe9'); + ).toThrow('Invalid address "0xe9".'); }); });